Kỹ thuật lập trình 501127 – HK2/2011-2012 1 
Ỹ UẬ LẬ Ì 
ài p 5 – ầ 14 
ệ q , ấp p độ g và kiể rỏ 
ài p bắ b ộ : 
Bài 1. Viết hàm đệ quy để tính tổng các số từ 1 đến n, với n được cho bởi user. 
//return the sum 1+ 2+ 3+ ...+ n 
int sum(int n) 
int sum(int n){ 
if (n<=0){ 
return 0; 
}else{ 
return n+sum(n-1); 
} 
} 
Bài 2. Viết hàm đệ quy để viết chương trình tìm giá trị lớn nhất của một mảng số nguyên. 
//return the maximum element in a[] 
int findmin(int a[], int n) 
int findmax(int a[],int n){ 
if (n==1){ 
return a[0]; 
}else{ 
return (a[n-1]>findmax(a,n-1))?a[n]:findmax(a,n-1); 
} 
} 
Bài 3. 
#include<iostream.h> 
#include <stdlib.h> 
#include<time.h> 
void output(int** c, int m, int n) { 
for (int i = 0; i < m; i++) { 
for (int j = 0; j < n; j++) { 
cout<<c[i][j]<<" "; 
} 
cout<<endl; 
} 
} 
void deleteMatrix(int** d, int m) { 
for (int i = 0; i < m; i++) { 
delete [] d[i]; 
}
Kỹ thuật lập trình 501127 – HK2/2011-2012 2 
delete []d; 
} 
void main() { 
int m, n; 
int** a; 
int** b; 
cout<<"Input the dimensions of the Matrix : "; 
cin>>m>>n; 
if (m <= 0 || n <= 0) { 
cout<<"Invalid Input !"<<endl; 
} else { 
init(a, m, n); 
cout<<"The random matrix : "<<endl; 
output(a, m, n); 
transposeMatrix(a, m, n, b); 
cout<<"The transposing matrix : "<<endl; 
output(b, n, m); 
deleteMatrix(a, m); 
deleteMatrix(b, n); 
} 
} 
Hãy hiện thực hàm init() và hàm transposeMatrix() thỏa mãn các yêu cầu sau: 
• init(): tạo ra ma trận a (m hàng , n cột) chứa các số nguyên bằng cách cấp phát động 
cho biến con trỏ a. Sau đó khởi tạo ma trận a chứa các số nguyên ngẫu nhiên từ 0..9 ( Gợi 
ý : sử dụng hàm rand() trong thư viện stdlib.h đã được include sẵn). 
• transposeMatrix() : tạo ma trận b (n hàng, m cột) chứa các số nguyên bằng cách 
cấp phát động cho biến con trỏ b. Sau đó, tạo ra ma trận chuyển vị của ma trận a và chứa 
vào ma trận b. 
void init(int**&a, int m, int n){ 
srand(time(NULL)); 
a=new int*[m]; 
for(int i=0;i<m;i++){ 
a[i]=new int[n]; 
for(int j=0;j<n;j++){ 
a[i][j]=rand()%10; 
} 
} 
} 
void transposeMatrix(int **a, int m,int n, int **&b){ 
b=new int*[n]; 
for(int i=0;i<n;i++){ 
b[i]=new int[m]; 
for(int j=0;j<m;j++){
Kỹ thuật lập trình 501127 – HK2/2011-2012 3 
b[i][j]=a[j][i]; 
} 
} 
} 
Bài 4. Sử dụng hàm đệ quy để viết chương trình đảo ngược một số nguyên. 
// with the parameter 12345, it would return 54321 
int reverseDigits(int n) 
int reverseDigits(int n){ 
static int s=0; 
if((n/10)==0){ 
return s+n%10; 
}else{ 
s=(n%10+s)*10; 
return reverseDigits(n/10); 
} 
} 
Bài p làm thêm 
Bài 5. Viết hàm đệ quy sumEvenDigit(int n) thực hiện chức năng sau: 
• Trả về -1 nếu n < 0. 
• Trả về tổng của các chữ số chẵn của số n nếu n >= 0. 
Ví dụ : n = 1468952 thì kết quả là : 4 + 6 + 8 + 2 = 20. 
int sumEvenDigit(int n){ 
if (n < 0){ 
return -1; 
}else if(n==0){ 
return 0; 
}else{ 
return ((n%10)%2==0?n%10:0)+sumEvenDigit(n/10); 
} 
} 
Bài 6. Cho đoạn chương trình : 
#include <iostream.h> 
void printCombinations(int m, int n) { 
//Coding here 
} 
void main() { 
int m,n; 
cout<<"Input two positive integer : "; 
cin>>m>>n; 
if (m <=0 || n <= 0 || m > n) { 
cout<<"Invalid input !"<<endl;
Kỹ thuật lập trình 501127 – HK2/2011-2012 4 
} else { 
cout<<"The result is : "<<endl; 
printCombinations(m,n); 
} 
} 
Hãy hiện thực hàm printCombinations() để sinh ra tất cả các tổ hợp chập m của n 
phần tử từ 1..n. Yêu cầu trong hàm printCombinations() phải gọi 1 hàm đệ qui để 
thực hiện việc sinh ra tất cả các tổ hợp này. 
Ví dụ : m = 2 , n = 4. Kết quả xuất ra màn hình sẽ là: 
1 2 
1 3 
1 4 
2 3 
2 4 
3 4 
void generate(int a[], int m, int n, int k){ 
for(int j=a[k-1]+1;j<=n-m+k;j++){ 
a[k]=j; 
if(k==m){ 
for (int i=1;i<=m;i++) cout<<a[i]<<" "; 
cout<<endl; 
}else 
generate(a,m,n,k+1); 
} 
} 
void printCombinations(int m, int n) { 
int k=1; 
int a[m+1]; 
a[0]=0; 
generate(a,m,n,k); 
} 
Bài 7. Viết chương trình xuất tam giác Pascal ra màn hình. Cụ thể như sau: 
• Nhập một số nguyên dương từ bàn phím (lưu vào biến n). 
• Tính toán tam giác Pascal đến mức n và lưu vào 1 mảng 2 chiều (Yêu cầu: mảng 2 
chiều này phải được cấp phát động vừa đủ với kích thước của tam giác Pascal). 
• Xuất mảng 2 chiều này ra màn hình. 
Định nghĩa: Tam giác Pascal chứa các hệ số khi khai triển nhị thức Newton (x + 1)n. 
Ví dụ: n = 4. Kết quả xuất ra màn hình sẽ là: 
1 
1 1 
1 2 1 
1 3 3 1 
1 4 6 4 1
Kỹ thuật lập trình 501127 – HK2/2011-2012 5 
#include<iostream> 
using namespace std; 
void initpascal(int**&a, int n){ 
a=new int*[n+1]; 
for(int i=0;i<n+1;i++){ 
a[i]=new int[i+1]; 
for(int j=0;j<i+1;j++){ 
a[i][j]=0; 
} 
} 
} 
void tamgiacpascal(int **&a, int n){ 
for(int i=0;i<n+1;i++){ 
a[i][0]=a[i][i]=1; 
for(int j=1;j<i;j++){ 
a[i][j]=a[i-1][j-1]+a[i-1][j]; 
} 
} 
} 
void output(int** c, int n) { 
for (int i = 0; i < n+1; i++) { 
for (int j = 0; j < i+1; j++) { 
cout<<c[i][j]<<"t"; 
} 
cout<<endl; 
} 
} 
void deleteMatrix(int** d, int n) { 
for (int i = 0; i < n+1; i++) { 
delete [] d[i]; 
} 
delete []d; 
} 
int main() { 
int n; 
int** a; 
cout<<"Nhap n: "; 
cin>>n; 
if (n <= 0) { 
cout<<"Invalid Input !"<<endl; 
} else { 
initpascal(a,n); 
tamgiacpascal(a,n); 
cout<<"Tam giac pascal: "<<endl; 
output(a, n);
Kỹ thuật lập trình 501127 – HK2/2011-2012 6 
deleteMatrix(a, n); 
} 
return 0; 
} 
Bài 8. Viết chương trình xuất ra ma trận xoắn ốc. Cụ thể như sau: 
• Nhập kích thước của ma trận từ bàn phím (lưu vào 2 biến m, n). 
• Tính toán ma trận xoắn ốc và lưu vào 1 mảng 2 chiều ( Yêu cầu : mảng 2 chiều này 
được cấp phát động). 
• Xuất ma trận xoắn ốc ra màn hình. 
Định nghĩa: Ma trận xoắn ốc là ma trận chứa đựng các số từ 1..(m x n) được sắp xếp có 
thứ tự tăng dần theo hình xoắn ốc. 
Ví dụ : 
m = 3, n = 5. Kết quả xuất ra màn hinh sẽ là: 
1 2 3 4 5 
12 13 14 15 6 
11 10 9 8 7 
m = 4, n = 4. Kết quả xuất ra màn hình sẽ là: 
1 2 3 4 
12 13 14 5 
11 16 15 6 
10 9 8 7 
#include<iostream> 
using namespace std; 
void init(int**&a, int m, int n){ 
a=new int*[m]; 
for(int i=0;i<m;i++){ 
a[i]=new int[n]; 
for(int j=0;j<n;j++){ 
a[i][j]=0; 
} 
} 
} 
void mtxoanoc(int **&a, int m, int n){ 
int i,j,istart,jstart,inccol,incrow,max; 
i=j=istart=jstart=0; 
inccol=1; 
incrow=0; 
max=m*n; 
for(int key=1;key<=max;key++){ 
a[i][j]=key; 
i+=incrow; 
j+=inccol; 
if(i==istart&&j==jstart){
Kỹ thuật lập trình 501127 – HK2/2011-2012 7 
incrow=0; 
inccol=1; 
i=j=++istart; 
n--; 
m--; 
}else if(i==istart&&j==n-1){ 
incrow=1; 
inccol=0; 
}else if(i==m-1&&j==n-1){ 
incrow=0; 
inccol=-1; 
}else if(i==m-1&&j==jstart){ 
incrow=-1; 
inccol=0; 
}else; 
} 
} 
void output(int** c, int m, int n) { 
for (int i = 0; i < m; i++) { 
for (int j = 0; j < n; j++) { 
cout<<c[i][j]<<"t"; 
} 
cout<<endl; 
} 
} 
void deleteMatrix(int** d, int m) { 
for (int i = 0; i < m; i++) { 
delete [] d[i]; 
} 
delete []d; 
} 
int main() { 
int m, n; 
int** a; 
cout<<"Input the dimensions of the Matrix : "; 
cin>>m>>n; 
if (m <= 0 || n <= 0) { 
cout<<"Invalid Input !"<<endl; 
} else { 
init(a, m, n); 
cout<<"Ma tran zero: "<<endl; 
output(a, m, n); 
mtxoanoc(a, m, n); 
cout<<"Ma tran xoan oc: "<<endl; 
output(a, m, n);
Kỹ thuật lập trình 501127 – HK2/2011-2012 8 
deleteMatrix(a, m); 
} 
return 0; 
} 
Bài 9. Bằng cách sử dụng kỹ thuật hàm đệ quy để viết chương trình kiểm tra xem đảo 
ngược một chuỗi có phải là chính nó hay không. 
//returns 1 if a[] is a palindrome, 0 otherwise 
int ispalindrome(char a[], int n) 
int ispalindrome(char a[], int n){ 
static int pos=0; 
if(pos>n/2){ 
return 1; 
}else if(a[pos]==a[n-1-pos]){ 
pos++; 
return 1*ispalindrome(a, n); 
}else { 
return -1; 
} 
} 
Bài 10. Dùng đệ quy để viết chương trình xuất ra một chuỗi mới được tạo thành bởi sao 
chép n chuỗi con s. 
// with the parameters “Hello” and 2 would return the 
string “HelloHello”. 
// if n equals zero, the method should return the empty 
string. 
char* repeat(char* s, int n) 
char* repeat(char* s, int n){ 
static char *s1=new char; 
if(n<=0){ 
s1=""; 
return s1; 
}else if(n==1){ 
strcat(s1,s); 
return s1; 
}else{ 
strcat(s1,s); 
return repeat(s,n-1); 
} 
} 
Bài 11. Hiện thực thuật giải tìm ước số chung lớn nhất bằng kỹ thuật đệ quy. 
int UCLN(int a, int b){
Kỹ thuật lập trình 501127 – HK2/2011-2012 9 
if (a==b){ 
return a; 
}else if (a>b){ 
return UCLN(a-b,b); 
}else{ 
return UCLN(b,b-a); 
} 
} 
Bài 12. Viết chương trình giải bài toán tháp Hà Nội. 
#include<iostream> 
using namespace std; 
void thapHN(int n, int i, int j){ 
int k; 
if(n==1) 
cout<<i<<" --> "<<j<<endl; 
else { 
k = 6-i-j; 
thapHN(n-1,i,k); 
thapHN(1,i,j); 
thapHN(n-1,k,j); 
} 
} 
int main() 
{ 
int sotang ; 
cout << "So tang = " ; 
cin >> sotang; 
thapHN(sotang, 1, 2); 
return 0; 
} 
-- ế -

Tut5 solution

  • 1.
    Kỹ thuật lậptrình 501127 – HK2/2011-2012 1 Ỹ UẬ LẬ Ì ài p 5 – ầ 14 ệ q , ấp p độ g và kiể rỏ ài p bắ b ộ : Bài 1. Viết hàm đệ quy để tính tổng các số từ 1 đến n, với n được cho bởi user. //return the sum 1+ 2+ 3+ ...+ n int sum(int n) int sum(int n){ if (n<=0){ return 0; }else{ return n+sum(n-1); } } Bài 2. Viết hàm đệ quy để viết chương trình tìm giá trị lớn nhất của một mảng số nguyên. //return the maximum element in a[] int findmin(int a[], int n) int findmax(int a[],int n){ if (n==1){ return a[0]; }else{ return (a[n-1]>findmax(a,n-1))?a[n]:findmax(a,n-1); } } Bài 3. #include<iostream.h> #include <stdlib.h> #include<time.h> void output(int** c, int m, int n) { for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { cout<<c[i][j]<<" "; } cout<<endl; } } void deleteMatrix(int** d, int m) { for (int i = 0; i < m; i++) { delete [] d[i]; }
  • 2.
    Kỹ thuật lậptrình 501127 – HK2/2011-2012 2 delete []d; } void main() { int m, n; int** a; int** b; cout<<"Input the dimensions of the Matrix : "; cin>>m>>n; if (m <= 0 || n <= 0) { cout<<"Invalid Input !"<<endl; } else { init(a, m, n); cout<<"The random matrix : "<<endl; output(a, m, n); transposeMatrix(a, m, n, b); cout<<"The transposing matrix : "<<endl; output(b, n, m); deleteMatrix(a, m); deleteMatrix(b, n); } } Hãy hiện thực hàm init() và hàm transposeMatrix() thỏa mãn các yêu cầu sau: • init(): tạo ra ma trận a (m hàng , n cột) chứa các số nguyên bằng cách cấp phát động cho biến con trỏ a. Sau đó khởi tạo ma trận a chứa các số nguyên ngẫu nhiên từ 0..9 ( Gợi ý : sử dụng hàm rand() trong thư viện stdlib.h đã được include sẵn). • transposeMatrix() : tạo ma trận b (n hàng, m cột) chứa các số nguyên bằng cách cấp phát động cho biến con trỏ b. Sau đó, tạo ra ma trận chuyển vị của ma trận a và chứa vào ma trận b. void init(int**&a, int m, int n){ srand(time(NULL)); a=new int*[m]; for(int i=0;i<m;i++){ a[i]=new int[n]; for(int j=0;j<n;j++){ a[i][j]=rand()%10; } } } void transposeMatrix(int **a, int m,int n, int **&b){ b=new int*[n]; for(int i=0;i<n;i++){ b[i]=new int[m]; for(int j=0;j<m;j++){
  • 3.
    Kỹ thuật lậptrình 501127 – HK2/2011-2012 3 b[i][j]=a[j][i]; } } } Bài 4. Sử dụng hàm đệ quy để viết chương trình đảo ngược một số nguyên. // with the parameter 12345, it would return 54321 int reverseDigits(int n) int reverseDigits(int n){ static int s=0; if((n/10)==0){ return s+n%10; }else{ s=(n%10+s)*10; return reverseDigits(n/10); } } Bài p làm thêm Bài 5. Viết hàm đệ quy sumEvenDigit(int n) thực hiện chức năng sau: • Trả về -1 nếu n < 0. • Trả về tổng của các chữ số chẵn của số n nếu n >= 0. Ví dụ : n = 1468952 thì kết quả là : 4 + 6 + 8 + 2 = 20. int sumEvenDigit(int n){ if (n < 0){ return -1; }else if(n==0){ return 0; }else{ return ((n%10)%2==0?n%10:0)+sumEvenDigit(n/10); } } Bài 6. Cho đoạn chương trình : #include <iostream.h> void printCombinations(int m, int n) { //Coding here } void main() { int m,n; cout<<"Input two positive integer : "; cin>>m>>n; if (m <=0 || n <= 0 || m > n) { cout<<"Invalid input !"<<endl;
  • 4.
    Kỹ thuật lậptrình 501127 – HK2/2011-2012 4 } else { cout<<"The result is : "<<endl; printCombinations(m,n); } } Hãy hiện thực hàm printCombinations() để sinh ra tất cả các tổ hợp chập m của n phần tử từ 1..n. Yêu cầu trong hàm printCombinations() phải gọi 1 hàm đệ qui để thực hiện việc sinh ra tất cả các tổ hợp này. Ví dụ : m = 2 , n = 4. Kết quả xuất ra màn hình sẽ là: 1 2 1 3 1 4 2 3 2 4 3 4 void generate(int a[], int m, int n, int k){ for(int j=a[k-1]+1;j<=n-m+k;j++){ a[k]=j; if(k==m){ for (int i=1;i<=m;i++) cout<<a[i]<<" "; cout<<endl; }else generate(a,m,n,k+1); } } void printCombinations(int m, int n) { int k=1; int a[m+1]; a[0]=0; generate(a,m,n,k); } Bài 7. Viết chương trình xuất tam giác Pascal ra màn hình. Cụ thể như sau: • Nhập một số nguyên dương từ bàn phím (lưu vào biến n). • Tính toán tam giác Pascal đến mức n và lưu vào 1 mảng 2 chiều (Yêu cầu: mảng 2 chiều này phải được cấp phát động vừa đủ với kích thước của tam giác Pascal). • Xuất mảng 2 chiều này ra màn hình. Định nghĩa: Tam giác Pascal chứa các hệ số khi khai triển nhị thức Newton (x + 1)n. Ví dụ: n = 4. Kết quả xuất ra màn hình sẽ là: 1 1 1 1 2 1 1 3 3 1 1 4 6 4 1
  • 5.
    Kỹ thuật lậptrình 501127 – HK2/2011-2012 5 #include<iostream> using namespace std; void initpascal(int**&a, int n){ a=new int*[n+1]; for(int i=0;i<n+1;i++){ a[i]=new int[i+1]; for(int j=0;j<i+1;j++){ a[i][j]=0; } } } void tamgiacpascal(int **&a, int n){ for(int i=0;i<n+1;i++){ a[i][0]=a[i][i]=1; for(int j=1;j<i;j++){ a[i][j]=a[i-1][j-1]+a[i-1][j]; } } } void output(int** c, int n) { for (int i = 0; i < n+1; i++) { for (int j = 0; j < i+1; j++) { cout<<c[i][j]<<"t"; } cout<<endl; } } void deleteMatrix(int** d, int n) { for (int i = 0; i < n+1; i++) { delete [] d[i]; } delete []d; } int main() { int n; int** a; cout<<"Nhap n: "; cin>>n; if (n <= 0) { cout<<"Invalid Input !"<<endl; } else { initpascal(a,n); tamgiacpascal(a,n); cout<<"Tam giac pascal: "<<endl; output(a, n);
  • 6.
    Kỹ thuật lậptrình 501127 – HK2/2011-2012 6 deleteMatrix(a, n); } return 0; } Bài 8. Viết chương trình xuất ra ma trận xoắn ốc. Cụ thể như sau: • Nhập kích thước của ma trận từ bàn phím (lưu vào 2 biến m, n). • Tính toán ma trận xoắn ốc và lưu vào 1 mảng 2 chiều ( Yêu cầu : mảng 2 chiều này được cấp phát động). • Xuất ma trận xoắn ốc ra màn hình. Định nghĩa: Ma trận xoắn ốc là ma trận chứa đựng các số từ 1..(m x n) được sắp xếp có thứ tự tăng dần theo hình xoắn ốc. Ví dụ : m = 3, n = 5. Kết quả xuất ra màn hinh sẽ là: 1 2 3 4 5 12 13 14 15 6 11 10 9 8 7 m = 4, n = 4. Kết quả xuất ra màn hình sẽ là: 1 2 3 4 12 13 14 5 11 16 15 6 10 9 8 7 #include<iostream> using namespace std; void init(int**&a, int m, int n){ a=new int*[m]; for(int i=0;i<m;i++){ a[i]=new int[n]; for(int j=0;j<n;j++){ a[i][j]=0; } } } void mtxoanoc(int **&a, int m, int n){ int i,j,istart,jstart,inccol,incrow,max; i=j=istart=jstart=0; inccol=1; incrow=0; max=m*n; for(int key=1;key<=max;key++){ a[i][j]=key; i+=incrow; j+=inccol; if(i==istart&&j==jstart){
  • 7.
    Kỹ thuật lậptrình 501127 – HK2/2011-2012 7 incrow=0; inccol=1; i=j=++istart; n--; m--; }else if(i==istart&&j==n-1){ incrow=1; inccol=0; }else if(i==m-1&&j==n-1){ incrow=0; inccol=-1; }else if(i==m-1&&j==jstart){ incrow=-1; inccol=0; }else; } } void output(int** c, int m, int n) { for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { cout<<c[i][j]<<"t"; } cout<<endl; } } void deleteMatrix(int** d, int m) { for (int i = 0; i < m; i++) { delete [] d[i]; } delete []d; } int main() { int m, n; int** a; cout<<"Input the dimensions of the Matrix : "; cin>>m>>n; if (m <= 0 || n <= 0) { cout<<"Invalid Input !"<<endl; } else { init(a, m, n); cout<<"Ma tran zero: "<<endl; output(a, m, n); mtxoanoc(a, m, n); cout<<"Ma tran xoan oc: "<<endl; output(a, m, n);
  • 8.
    Kỹ thuật lậptrình 501127 – HK2/2011-2012 8 deleteMatrix(a, m); } return 0; } Bài 9. Bằng cách sử dụng kỹ thuật hàm đệ quy để viết chương trình kiểm tra xem đảo ngược một chuỗi có phải là chính nó hay không. //returns 1 if a[] is a palindrome, 0 otherwise int ispalindrome(char a[], int n) int ispalindrome(char a[], int n){ static int pos=0; if(pos>n/2){ return 1; }else if(a[pos]==a[n-1-pos]){ pos++; return 1*ispalindrome(a, n); }else { return -1; } } Bài 10. Dùng đệ quy để viết chương trình xuất ra một chuỗi mới được tạo thành bởi sao chép n chuỗi con s. // with the parameters “Hello” and 2 would return the string “HelloHello”. // if n equals zero, the method should return the empty string. char* repeat(char* s, int n) char* repeat(char* s, int n){ static char *s1=new char; if(n<=0){ s1=""; return s1; }else if(n==1){ strcat(s1,s); return s1; }else{ strcat(s1,s); return repeat(s,n-1); } } Bài 11. Hiện thực thuật giải tìm ước số chung lớn nhất bằng kỹ thuật đệ quy. int UCLN(int a, int b){
  • 9.
    Kỹ thuật lậptrình 501127 – HK2/2011-2012 9 if (a==b){ return a; }else if (a>b){ return UCLN(a-b,b); }else{ return UCLN(b,b-a); } } Bài 12. Viết chương trình giải bài toán tháp Hà Nội. #include<iostream> using namespace std; void thapHN(int n, int i, int j){ int k; if(n==1) cout<<i<<" --> "<<j<<endl; else { k = 6-i-j; thapHN(n-1,i,k); thapHN(1,i,j); thapHN(n-1,k,j); } } int main() { int sotang ; cout << "So tang = " ; cin >> sotang; thapHN(sotang, 1, 2); return 0; } -- ế -