Ôn tập giữ kỳ Ôn tập giữa kỳ Trịnh Tấn Đạt Khoa CNTT Đại Học Sài Gòn Email trinhtandatsgu edu vn Website https sites google comsitettdat88 1) Cho file input txt như sau 127 19 101 11 10 2 5 100 31 a) Đọc file và lưu trữ bằng mảng một chiều sử dụng con trỏ b) Tính tổng các phần tử của mảng c) Hai số nguyên dương a và b gọi là nguyên tố cùng nhau nếu ước số chung lớn nhất của chúng là 1 Đếm xem trong file input có bao nhiêu cặp số nguyên tố cùng nhau d) Tìm giá trị lớn thứ nhất, thứ nhì của.
Trang 21) Cho file input.txt như sau:
127 19 101 11 10 2 5 100 31a) Đọc file và lưu trữ bằng mảng một chiều sử dụng con trỏ
b) Tính tổng các phần tử của mảng
c) Hai số nguyên dương a và b gọi là nguyên tố cùng nhau nếu ước số chung lớn
nhất của chúng là 1 Đếm xem trong file input có bao nhiêu cặp số nguyên tốcùng nhau
d) Tìm giá trị lớn thứ nhất, thứ nhì của dãy
e) Tìm dãy con liên tiếp không giảm dài nhất In ra chiều dài dãy con tìm đượcf) Sắp xếp mảng tăng dần
* Yêu cầu: Kết quả ghi vào file output.txt (thay vì in ra màn hình)
Trang 3void readFromFile(FILE *file , int *&Arr, int &n)
// cap phat dong nhung chua biet chinh xac so luong phan tuArr = new int[100];
n = 0;
// doc tung phan tu tu file va luu vao mang
// cho den khi het file EOF
Trang 4int Tongmang(int *Arr, int n) {
Trang 5int gcd(int a, int b){
Trang 6int DemSNTCN(int *Arr, int n) { int i, j;
Trang 7void sapxeptang(int *&Arr, int n){
int i, j , temp;
for(i = 0;i<n-1;i++)
for (j=i+1;j<n;j++)
if(Arr[i]>Arr[j]){
temp = Arr[i];
Arr[i] = Arr[j];
Arr[j] = temp;
}}
Trang 8// in mang ra man hinh
for (int i = 0; i < n; i++)
Trang 9Bài tập
2) Cho file input.txt như sau:
+ Dòng đầu tiên: ghi số lượng phần tử n
+ Dòng tiếp theo: ghi n số nguyên, các nhau ít nhất một khoảng trắng
1 2 -5 4 -10 6 8
Trang 10void readFromFile(FILE *file , int *&Arr, int &n) {
// doc dong dau tien trong file
// luu so luong phan tu n
fscanf(file, "%d", &n);
Arr = new int[n]; // cap phat dong
// doc tung phan tu tu file va luu vao mang for (int i = 0; i < n; i++)
fscanf(file, "%d", &Arr[i]);
}
Trang 11void sapxepgiam(int *&Arr, int n){
int i, j , temp;
for(i = 0;i<n-1;i++)
for (j=i+1;j<n;j++)
if(Arr[i]<Arr[j]){
temp = Arr[i];
Arr[i] = Arr[j];
Arr[j] = temp;
}}
Trang 13int i= 0, tong = 0, temp;
for (i = 0; i< n; i++)
if(Arr[i]>0)
tong = tong+countdigits(Arr[i]); return tong;
}
Trang 14// in mang ra man hinh
for (int i = 0; i < n; i++)
fclose(fo);
return 0;
}
Trang 15Ví dụ
Đọc ghi FILE cho mảng 2 chiều (dùng dạng 1)
▪ Tạo file input_2.txt có dạng sau
- Tìm giá trị nhỏ nhất của các giá trị lớn nhất trên mỗi cột
- Tạo mảng B từ mảng A sao cho
bij = aij * tj ( tj là giá trị lớn nhất trên cột j)
Trang 16int maxcot(int a[][100], int m, int n, int c)
{ int i;
//xet cot c
int maxc = a[0][c]; // linh canh tai dong 0 cot c
for (i= 1; i<m; i++)
Trang 17int findmin(int a[][100],int m, int n)
Trang 18void taomangB(int a[][100], int m, int n, int b[][100])
{
// tao mang b tu mang a
for (int j= 0; j< n ; j++) // duyet cot
{
int maxc = maxcot(a,m,n,j); // max cot jfor (int i=0;i<m ; i++) // duyet theo dong{
b[i][j] = a[i][j] * maxc;
}}
}
-Tạo mảng B từ mảng A sao cho
bij = aij * tj ( tj là giá trị lớn nhất trên cột j)
Trang 19c) Sắp xếp mảng theo quy luật:
- Các số chẵn (nếu có) ở đầu mảng và có thứ tự giảm dần
- Các số lẻ (nếu có) ở cuối mảng và có thứ tự tăng dần
Trang 20s=s+a[i];
d++;
}}
return s/d;
}
Trang 21b) Tìm số nguyên tố lớn nhất nhỏ hơn tất cả các giá trị có trong mảng (Nếu không tồn tại giá trị thỏa điều kiện xuất ra giá trị -1.)
int ktsnt(int n) {
if(a[i]<min) min=a[i];
} return min;
i ;
} cout<<" Cau 1.b:" <<i<<endl;
}
else
cout<<" Cau1.b: -1"<<endl;
}
Trang 22BT 2
a)
a) Phát sinh ngẫu nhiên một ma trận thưa kích thước N x N (N>=3) các số nguyên dương trong đoạn [1, 1000] (các phần tử khác 0 trong ma trận được tạo ngẫu nhiên - vị trí và giá trị)
Yêu cầu số lượng các phần tử khác 0 phải lớn hơn 1 và nhỏ hơn (N*N)/2 ( tổng số lượng các phần tử khác 0 được nhập từ bàn phím)
In ma trận ra màn hình
Trang 23Hàm khởi tạo ma trận toàn số 0
void tao_mang_so_0(int a[][100], int N)
Trang 24void tao_ma_tran_thua_2a(int a[][100], int &N, int &K)
{ N = 3+rand()%(6-3+1); // N thuoc[3,6]
tao_mang_so_0(a,N); // tao mang toan so 0
K= 1+ rand()%((N*N)/2); // so luong phan tu khac 0
continue;
} else { // khong bi trung
cout <<"vi tri:"<< i << " " << j << endl;
a[i][j]=1+rand()%1000;
dem ++ ; // them vao 1 vi tri
} }
}
Trang 25b) Chuyển sang triples
void tao_ma_tran_triples(int a[][100], int N, int K, int triples[][100]){
int i, j, index;
index = 0; // chi so cot trong triples
for(int i=0;i<N;i++)
for(int j=0;j<N;j++){
}
Trang 26void xuat_ma_tran_triples(int triples[][100], int K) {
for (int i=0;i<3;i++)
Trang 27c) Chuyển vị triples
void chuyen_vi_triples(int triples[][100], int K) {
for(int i=0;i<K;i++)
{ // hoan vi gia tri dong va cot
int temp = triples[0][i];
triples[0][i] = triples[1][i];
triples[1][i] = temp;
}
}
Trang 28Chuyển triples sang ma trận gốc
void convert_triples_matrix(int triples[][100], int K, int b[][100], int N )
int dong = triples[0][j];
int cot = triples [1][j];
int value = triples[2][j];
b[dong][cot] = value;
}}
Trang 29Hàm main()
#include<iostream.h>
#include<math.h>
void tao_ma_tran_thua_2a(int a[][100], int &m, int &K);
void xuat_ma_tran_triples(int triples[][100], int K);
void tao_ma_tran_triples(int a[][100], int m, int K, int triples[][100]); void xuatmang2chieu(int a[][100], int m);
void convert_triples_matrix(int triples[][100], int K, int b[][100], int N ); void chuyen_vi_triples(int triples[][100], int K);
Trang 301) Cho một ma trận vuông A có kích thước NxN Tính tổng các
Trang 32void printSumSimple(int A[][n], int k)
// duyet ma tran kxk trong ma tran goc
for (int p=i; p<k+i; p++)
Trang 34Câu hỏi
CÂU 4 (3 điểm)
Cho mảng hai chiều a có m dòng và n cột (m,n 200); các phần tử là các số nguyên dương Các dòng được đánh số từ 1 đến m, các cột được đánh số từ 1 đến n
Hãy viết chương trình hoàn chỉnh thực hiện các công việc sau:
a) Tìm tổng các phần tử trong một bảng con 3 dòng và 3 cột sao cho tổng các số trong bảng con đó là lớn nhất
b) Tìm giá trị lớn nhất của các giá trị nhỏ nhất của từng dòng
Trang 35Bài Tập bổ sung
Cho một mảng một chiều các số nguyên có N phần tử Tìm bộ ba số trong mảng ( gọi
là triplet) có tổng bằng một số K cho trước
Trang 36Cách 1: dùng phương pháp vét cạn, duyệt qua toàn bộ cáctriplet có khả năng, tính tổng triplet và so sánh với K
Thuật toán này có độ phức tạp là O(n3) do sử dụng 3 vòng lặplồng nhau
Trang 37// Prints all triplets in arr[] with given sum
void findTriplets(int arr[], int n, int sum)
}
}
Trang 38- Duyệt qua từng phần tử a[i] (i từ 0 đến n-2) trên mảng đã sắp xếp
- Tại vị trí i đang xét phần tử a[i] Tìm trong phần mảng còn lại 2 số thỏa điều kiện
- Khởi tạo 2 chỉ số l = i+1 ( dùng để duyệt từ trái sang phải) ; r = n-1 (dùng để duyệt từ phải sang trái)
Step 3:
- while( l < r )
{ - Nếu tổng a[i]+a[l]+a[r] == K thì in ra triplet này và tăng l++, r++ (xét các tường hợp khác)
- Nếu tổng a[i]+a[l]+a[r] < K thì tăng l++
- Nếu tổng a[i]+a[l]+a[r] > K thì giảm r—
Ngược lại nếu không tồn tại triplet thì in ra ko tìm thấy
Trang 39Duyệt i =0, xét A[o] = -3, khởi tạo l = 1 (A[1] = -1) , r = 4 (A[4]=2)
- tính tổng A[0]+A[1]+A[4] = -2 == K … in triplet này ra (-3,-1,2) Sau đó l++ ( l = 2), r++ ( r = 3)
- tính tổng A[0]+A[2]+A[3] = -2 == K in in triplet này ra (-3, 0, 1) Sau đó l++ (l = 3), r++ ( r = 2) l > r → ngừng bước lặp i=0, xét tiếp i++
Duyệt i=1 , … // duyệt tương tự
Trang 40void findTriplets(int arr[], int n, int sum)
{ sapxeptang(arr,n); // goi ham sap xep mang tang dan
for (int i = 0; i < n - 1; i++) { // duyet qua tung vi tri a[i]
// khoi tao left and right trong phần mảng còn lại sau a[i]
int l = i + 1;
int r = n - 1;
int x = arr[i];
while (l < r) {
if ( x + arr[l] + arr[r] == sum ) {
cout << x << " " << arr[l] << " " << arr[r] << endl;
l++;
r ;
}
// nếu tổng triplet nhỏ hơn sum
else if ( x + arr[l] + arr[r] < sum )
Trang 41Bài tập Đệ quy
1 Tính S(n)=1-2+3-4+…+ ((-1)^(n+1))*n với n>0
a) dùng đệ quy
b) không dùng đệ quy
2.Viết hàm tính biểu thức U(n) sau đây, với n là số nguyên dương
3 Viết hàm tính số hạng thứ n của 2 dãy sau
Trang 42c) Đếm xem trong mảng có bao nhiêu số Mersenne Số Mersenne
là số biểu diễn được dưới dạng x = 2n-1
d) Đếm xem trong mảng có bao nhiêu số Armstrong Số
Armstrong là số mà từng chữ số trong số đó lũy thừa với số chữ số của nó bằng chính nó
Ví dụ : 153 = 1^3 + 5^3 + 3^3 => 153 là số Armstrong
137 1^3 + 3^3 + 7^3 = 371 => 137 không phải là sốArmstrong
Trang 43Bài Tập
e) Đếm xem có bao nhiêu số hoàn chỉnh Số hoàn chỉnh là số có giá trị bằng tổng các ước số của nó (không tính ước là chính sốđó)
Ví dụ: 28=1+2+4+7+14 là số hoàn chỉnh
6 = 1+2+3f) Tìm số chính phương lớn nhất, số nguyên tố lớn nhất, số
Mersenne lớn nhất, số Armstrong lớn nhất, số hoàn chỉnh lớn nhất(nếu có, nếu không có in ra thông báo)
g) Số nào trong mảng xuất hiện nhiều nhất, bao nhiêu lần?
h) Kiểm tra mảng có bao nhiêu số có giá trị khác nhau Sau đó xóacác phần tử trùng nhau (nếu có)
* Lưu ý: thu hồi vùng nhớ khi kết thúc chương trình
Trang 44a) Viết hàm nhập và xuất mảng 2 chiều.
b) Tạo mảng E từ mảng A sao cho eij là số lượng số chẵn bao
quanh aij (không kể chính số đó, xét 1 vị trí aij, ta có tối đa 8 hướng bao quanh aij) Mảng E cùng kích thước với mảng A
Có bao nhiêu số trong mảng E lớn hơn hoặc bằng 3
Trang 45Bài Tập Bổ Sung 2
c) Tìm bộ ba số (triplet) cùng thuộc một dòng nào đó trong mảng
A sao cho tổng các chữ số của 3 số đó là lớn nhất Hãy cho biếtdòng nào chứa 3 số thỏa điều kiện có tổng các chữ số là lớnnhất In ra tổng các chữ số của 3 số đó
d) Tìm số xuất hiện nhiều nhất trong mảng A Xuất hiện bao nhiêulần
Trang 46Bài tập
3) Mảng hai chiều
File input.txt có nội dung như sau
Trang 47Kết quả ghi ra file output.txt Yêu cầu sử dụng con trỏ biễu diễn mảng 2 chiều vàcấp phát động
Trang 48Ví dụ