Duyệt trên cây và bài toán biểu diễn tổng

Một phần của tài liệu giao trinh C(dttx) pot (Trang 153 - 157)

- Kết quả trả về của hàm là ký tự được ấn.

Bài toán tháp Hà nội được dặt ra như sau: Có một thá pm tầng đang dặt tại vị trí (x1,y1), cần chuyển đến vị trị mới (x2,y2) Khi chuyển cho phép

3.5. Duyệt trên cây và bài toán biểu diễn tổng

Bài toán duyệt trên cây có thể giải theo đệ qui như sau: Xuất phát từ một đỉnh nào đó ta thực hiện hai động tác:  Xét đỉnh này

 Đi đến các đỉnh kề nó bằng phép đệ qui

Bằng thủ tục nói trên có thể đi qua tất cả các đỉnh của một cây. Ta minh họa điều này bằng cách xét bài toán phân tích số n nguyên dương thành tổng các số nguyên dương nhỏ hơn n. Đỉnh xuất phát là n. Từ đỉnh này có thể đi đến các đỉnh gồm một cặp hai số có tổng bằng n, các đỉnh đó là:

(i,n-i), với i=1,...,n/2.

Tại mỗi đỉnh hai số lại có thể đi đến các đỉnh 3 số. Một cách tổng quát từ đỉnh k số: (a1,..., ak-1, ak)

có thể đi đến đỉnh k+1 số sau:

(a1,..., ak-1, i, ak-i), với i=ak-1,..., ak/2 Nhận xét: Mỗi dãy số tại đỉnh là đơn điệu tăng.

Có thể chứng minh mọi tổng đều ứng với một đỉnh nào đó thực vậy xét tổng (k+1) số: n=t1+t2+… + tk+tk+1

(Dãy ti không giảm). Rõ ràng tổng này có thể suy ra từ đỉnh gồm k số: (t1,...,tk-1, tk+tk+1)

Như vậy mỗi tổng (k+1) số đều có thể suy ra từ đỉnh k số. Do tập các tổng một số là đầy đủ chỉ gồm n, nên các tập k số cũng đầy đủ với mọi k >1. Đó là điều cần chứng minh.

Ta dùng mảng ngoài a[100] để chứa bộ số của đỉnh. Với đỉnh xuất phát thì: k=1 và a[1] =n

Vì cần dùng đến a[k-1], nên đưa thêm a[0]=1. Ta xây dựng hàm duyệt đỉnh k với nội dung sau:

1. 1. Xét đỉnh k>1 in các số a[1],..., a[k] dưới dạng tổng. a[1] +a[2]+...+ a[k]

(không xét đỉnh với k=1) 2. 2. Đi đến các đỉnh (k+1) số : (a1,...,ak-1,i,ak-i), với i=ak-1,...,ak/2

Hàm

void duyet_dinh(int k);

chương trình dưới đây sẽ lập theo thuật toán này:

/* Phân tích n và tổng các số nhỏ hơn n duyệt các đỉnh của cây bằng thủ tục đệ qui*/ #include<stdio.h>

#include<conio.h> int a[100];

/*Da biet a[0],..., a[k] */ void duyet_dinh(int k) { int x,i; /*xet dinh k>1*/ if(k>1) for(i=1;i<=k;++i) printf(“%c%d”,i>1?’+’:’\n’,a[i]); /*đi đến các đỉnh (k +1) số*/ x=a[k]; for (i=a[k-1];i<=x/2;++i) { a[k]=i; a[k+1]=x-i; duyet_dinh(k+1); } } void main() { int n; clrscr();

printf(“\nn=”); scanf(“%d”,&n); a[0]=1; a[1]=n;

duyet_dinh(1); getch(); }

4. BÀI TẬP MINH HOẠ

Bài 1

Viết hàm đệ qui để tính tổng sau: S=1+2+3+...+n /*Chương tình tính tổng S bằng hàm đệ qui*/ #include<stdio.h> int tongs(int n); main() { int n;

printf("Nhap vao so n de tinh tong: "); scanf("%d",&n);

/*In ra ket qua */

printf("\ntong S:=%d",tongs(n)); } int tongs(int n) { if (n==1) return 1; else return n+tong(n-1); } Bài 2

/*Chương trình minh họa tìm ước số chung lớn nhất bằng phương pháp đệ qui*/

#inclde<stdio.h> int uscln(int n,int m) void main()

{

int so1,so2;

printf(“Nhap so thu nhat:\n”); scanf(“%d”,&so1); printf(“Nhap so thu hai :\n”); scanf(“%d”,&so2); printf(“USCLN la %d”,uscln(so1,so2));

return; }

int uscln(int n,int m) {

r=n-m; if (r==0) return m; else return uscln(m,r); } Bài 3

/*Chương trình dùng kỹ thuật đệ qui để in ra số theo thứ tự ngược */

#inclde<stdio.h>

void daochuso(unsigned so); void main()

{

unsigned so;

printf(“Nhap vao mot so duong:”); scanf(“%u”,&so); daochso(so);

return; }

void daochuso(unsigned so) { printf(“%u”,so%10); if (so/10==0) return; else return daochuso(so/10); } 5. BÀI TẬP TỰ LÀM Bài 1

Cho trước hai số nguyên dương m,n. Viết hàm đệ qui để tính giá trị biểu thức sau: F(m,n)= 1 m 1+ 1 . 1+ 1 . 1+ ... 1 4 1+ 1 3 1+ 1 2 1+ 1 1 n

Viết chương trình áp dụng (Yêu cầu nhập vào m,n và hiển thị giá trị biểu thức )

Bài 2

F(n)=√3*n+... √9+√6+√3 n ... 3 2 1 Viết chương trình áp dụng

Bài 3

Cho trước hai số nguyên dương x,n. Viết các hàm đệ qui để tính giá trị biểu thức sau:

Viết chương trình áp dụng (yêu cầu nhập vào x,n và hiển thị giá trị biểu thức)

Bài 4

Tính các phần tử của tam giác Pascal.

Gợi ý:

•••

int nhithuc(int n,int p) { if(p==1 || p==n) return 1; else return(nhithuc(n-1,p-1)+nhithuc(n-1,p)); } ••• Bài 5

Viết chương trình tính tháp Hà Nội

Sử dụng hàm sau:

•••

void chuyen(int n,int s,int e,int m) {

if (n>0) {

chuyen(1,s,m,e);

printf(“Chuyen dich tu coc %d toi coc %d\n”,s,e); chuyen(n-1,m,e,s); } return; } ••• BÀI 14

Một phần của tài liệu giao trinh C(dttx) pot (Trang 153 - 157)

Tải bản đầy đủ (DOC)

(184 trang)
w