1. Trang chủ
  2. » Công Nghệ Thông Tin

kỹ thuật lập trình C chuyên nghiệp phần 10 pps

18 423 2
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 18
Dung lượng 570,39 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Thuật Thuật toán toán:: Xét Xét tất tất cả cả các các phần phần tử tử aaii với với i= i=11....nn Bỏ Bỏ hầ hầ tử tử khỏi khỏi dã dã ốố Bỏ Bỏ phần phần tử tử aaii ra ra khỏi khỏi dãy dãy s

Trang 1

ii Tìm Tìm kiếm kiếm nhị nhị phân phân pp

int

int searchBinary(int searchBinary(int left,int left,int right, right, intx){ intx){

if(left<right){ ( ( g ){ g ){

int

int mid=(left+right)/ mid=(left+right)/22;;

if(x==A[i])return

if(x==A[i])return ii;; ( ( [ ]) [ ]) ;;

if(x<A[i])return

if(x<A[i])return searchBinary(left,mid searchBinary(left,mid 11,x) ,x);;

return return searchBinary(mid+ searchBinary(mid+11,right,x) ,right,x);;

return

return searchBinary(mid searchBinary(mid 11,right,x) ,right,x);;

}}

return

return 11;;

return

return 11;;

}}

iii Phân Phân tích tích một một số số nguyên nguyên ra ra thừa thừa số số nguyên nguyên tố tố (( Bài

iii Phân Phân tích tích một một số số nguyên nguyên ra ra thừa thừa số số nguyên nguyên tố tố (( Bài

tập ))

Phạm Thế Bảo

Trang 2

2 Đệ Đệ quy quy nhánh nhánh

Là dạng dạng đệ đệ quy quy mà mà trong trong quá quá trình trình đệ đệ quy, quy, lời lời gọi gọi được được thực thực hiện hiện

nhiều

nhiều lần lần

Ví dụ dụ::

i.i Tháp Tháp Hà Hà nội nội

ii Liệt Liệt kê kê tất tất cả cả hoán hoán vị vị của của nn phần phần tử tử khác khác nhau nhau

ii Liệt Liệt kê kê tất tất cả cả hoán hoán vị vị của của nn phần phần tử tử khác khác nhau nhau

Thuật

Thuật toán toán::

Xét

Xét tất tất cả cả các các phần phần tử tử aaii với với i= i=11 nn Bỏ

Bỏ hầ hầ tử tử khỏi khỏi dã dã ốố Bỏ

Bỏ phần phần tử tử aaii ra ra khỏi khỏi dãy dãy số số Ghi

Ghi nhận nhận đã đã lấy lấy ra ra phần phần tử tử aaii Hoán

Hoán vị vị (Dãy (Dãy số) số)

Đ hầ hầ tử tử àà l i l i dã dã ốố Đưa

Đưa phần phần tử tử aaii vào vào lại lại dãy dãy số số Nếu

Nếu (Dãy (Dãy số) số) rỗng rỗng thì thì thứ thứ tự tự các các phần phần tử tử được được lấy lấy ra ra chính chính là là một

một hoán hoán vị vị

Bài Bài toán toán tô tô mà mà (floodfill) (floodfill)

iii Bài Bài toán toán tô tô màu màu (floodfill) (floodfill)

Phạm Thế Bảo

Trang 3

3 Đệ Đệ quy quy hỗ hỗ tương tương

Là dạng dạng đệ ạ g ạ g ệệ q y đệ quy quy mà q y mà trong trong đó gg đó việc việc gọi ệệ gọ gọi có gọ có xoay xoay vòng, yy vòng, như g, như A A

gọi

gọi B, B, B B gọi gọi C, C, và và C C gọi gọi A A Đây Đây là là trường trường hợp hợp rất rất phức phức

tạp

tạp

Ví dụ dụ::

i.i Đường Đường Hilbert Hilbert

ii Đường Đường Sierpinski Sierpinski

Phạm Thế Bảo

Trang 4

Cá h há khử đệ

Các phương pháp khử đệ quy

1 Vòng Vòng lặp lặp

2 Bằng Bằng stack stack

Phạm Thế Bảo

Trang 5

Đệ quy

„ Ví Ví dụ dụ: : Viết ụụ Viết chương chương trình gg trình nhập nhập số ập số tự tự nhiên ựự nhiên n n và và tính tính giai giai thừa gg thừa : n! : n!.

„ Giải Giải quyết quyết bài bài toán toán bằng bằng vòng vòng lặp lặp

1 #include < #include <stdio.h stdio.h> >

2 unsigned long unsigned long int int factorial( factorial(int int n) n)

3 { unsigned long f = 1;

4 for ( for (int int ii = 1; = 1; ii<=n; <=n; ii++) ++)

55 f *= f *= ii;;

5 f *= f *= ii;;

7 }}

8 int int main(void) main(void)

9 { { int int n; n;

10 printf printf(“ (“Nhap Nhap n:”); n:”); scanf scanf(“%d”, &n); (“%d”, &n);

10 printf printf(( Nhap Nhap n: ); n: ); scanf scanf( %d , &n); ( %d , &n);

printf

printf(“n! = %d! = %l (“n! = %d! = %l\\n”, n, factorial(n)); n”, n, factorial(n));

11 return 0;

12 }}

Trang 6

Đệ quy

„ Một Một hàm hàm được được gọi gọi là là đệ đệ quy quy nếu nếu như như trong trong quá quá trình trình xử xử lý, lý, hàm hàm này này có có một một lời lời gọi gọi

đến

đến chính chính nó nó

„ Giải Giải quyết quyết bài bài toán toán bằng bằng đệ đệ quy quy

1 #include #include <stdio <stdio h> h>

1 #include #include stdio stdio hh

2 unsigned unsigned long long int int factorial(int factorial(int n) n)

3 {{ if(n== if(n==00))

44 return return 11;;

4 return return 11;;

5 return return (n* (n* factorial(n factorial(n 11)) ));;

6 }}

7 int int main(void) main(void)

8 {{ int int nn;;

9 printf(“Nhap printf(“Nhap nn::”) ”);; scanf(“ scanf(“% %d”, d”, &n) &n);;

9 printf( Nhap printf( Nhap nn:: ));; scanf( scanf( % %d , d , &n) &n);;

10 printf(“n! printf(“n! = = % %d! d! = = % %ll\\n”, n”, n, n, factorial(n)) factorial(n));;

11 return return 00;;

12 }}

Trang 7

dừng

Bài

Bài t á t á iải iải bằ bằ th ật th ật iải iải đệ đệ hải hải óó điề điề kiệ kiệ

„ Bài Bài toán toán giải giải bằng bằng thuật thuật giải giải đệ đệ quy quy phải phải có có điều điều kiện kiện dừng

dừng

„ Thuật Thuật toán toán đệ đệ quy quy trên trên máy máy tính tính có có thể thể bị bị giới giới hạn hạn bởi bởi dung

dung lượng lượng bộ bộ nhớ nhớ do do lời lời gọi gọi hàm hàm liên liên tiếp tiếp

dung

dung lượng lượng bộ bộ nhớ nhớ do do lời lời gọi gọi hàm hàm liên liên tiếp tiếp

main

factorial (4) factorial (3) factorial (2) factorial (1)

Hãy

Hãy vẽ vẽ sơ sơ đồ đồ tiến tiến trình trình gọi gọi hàm hàm khi khi thực thực hiện hiện tính tính dãy dãy fibonacci fibonacci bằng bằng

Hãy

Hãy vẽ vẽ sơ sơ đồ đồ tiến tiến trình trình gọi gọi hàm hàm khi khi thực thực hiện hiện tính tính dãy dãy fibonacci fibonacci bằng bằng

đệ

đệ quy quy

Trang 8

Bài t á Thá Hà Nội

„ Có Có 33 cái cái cột cột và và một một chồng chồng đĩa đĩa ởở cột cột thứ thứ nhất nhất Hãy Hãy chuyển chuyển

„ Có Có 33 cái cái cột cột và và một một chồng chồng đĩa đĩa ởở cột cột thứ thứ nhất nhất Hãy Hãy chuyển chuyển chồng

chồng đĩa đĩa sang sang cột cột thứ thứ ba ba với với điều điều kiện kiện mỗi mỗi lần lần di di chuyển chuyển chỉ

chỉ một một đĩa đĩa và và các các đĩa đĩa bé bé luôn luôn nằm nằm trên trên đĩa đĩa lớn lớn

Trang 9

Th ật iải

Ch ể

„ Chuyển Chuyển (n (n 11)) đĩa đĩa sang sang cột cột trung trung gian gian

„ Chuyển Chuyển đĩa đĩa lớn lớn nhất nhất sang sang cột cột đích đích

Ch ể

Ch ể (( 11)) đĩ đĩ từ từ ột ột tt ii ột ột đí h đí h

„ Chuyển Chuyển (n (n 11)) đĩa đĩa từ từ cột cột trung trung gian gian sang sang cột cột đích đích

Trang 10

Cài đặt bằ đệ

Cài đặt bằng đệ quy

11 MoveDisk MoveDisk((disk number disk number starting post starting post target post target post

1 MoveDisk MoveDisk((disk_number disk_number, , starting_post starting_post, , target_post target_post,,

intermediate_post

intermediate_post))

2 {{

33 if(disk)number > 1)

3 if(disk)number > 1)

5 MoveDisk MoveDisk(disk_number (disk_number 1, 1, starting_post starting_post, ,

intermediate post intermediate post target post target post); );

intermediate_post

intermediate_post, , target_post target_post); );

6 printf printf(“Move disk number %d, from post %d to post %d (“Move disk number %d, from post %d to post %d.\\n”, n”,

disk_number

disk_number, , starting_post starting_post, , target_post target_post); );

77 MoveDisk MoveDisk(disk number (disk number 1 intermediate post 1 intermediate post

7 MoveDisk MoveDisk(disk_number (disk_number 1,intermediate_post, 1,intermediate_post,

target_post

target_post, , starting_post starting_post); );

10 printf printf(“Move disk number 1 from post %d to post %d (“Move disk number 1 from post %d to post %d.\\n”, n”,

starting_post

starting_post, , target_post target_post); );

11 }}

11 }}

Trang 11

Bài toán Xếp Hậu (8 Queens)

Liệt kê tất cả các cách xếp n quân hậu trên bàn cờ n x n sao cho chúng không ăn được nhau

Bàn cờ có n hàng được đánh số từ 0 đến n-1, n cột được đánh số từ 0 đến n-1; Bàn cờ có n*2

-1 đường chéo xuôi được đánh số từ 0 đến 2*n -2, 2 *n -1 đường chéo ngược được đánh số từ 2*n -2 Ví dụ: với bàn cờ 8 x 8, chúng ta có 8 hàng được đánh số từ 0 đến 7, 8 cột được đánh

số từ 0 đến 7, 15 đường chéo xuôi, 15 đường chéo ngược được đánh số từ 0 15

Vì trên mỗi hàng chỉ xếp được đúng một quân hậu, nên chúng ta chỉ cần quan tâm đến quân

hậu được xếp ở cột nào Từ đó dẫn đến việc xác định bộ n thành phần x1, x2, , xn,trong đó

xi = j được hiểu là quân hậu tại dòng i xếp vào cột thứ j Giá trị của i được nhận từ 0 đến n-1;

giá trị của j cũng được nhận từ 0 đến n-1, nhưng thoả mãn điều kiện ô (i,j) chưa bị quân hậu

khác chiếu đến theo cột, đường chéo xuôi, đường chéo ngược

Việc kiểm soát theo hàng ngang là không cần thiết vì trên mỗi hàng chỉ xếp đúng một quân

hậu Việc kiểm soát theo cột được ghi nhận nhờ dãy biến logic aj với qui ước aj=1nếu cột j còn trống, cột aj=0 nếu cột j không còn trống Để ghi nhận đường chéo xuôi và đường chéo ngược có chiếu tới ô (i,j) hay không, ta sử dụng phương trình i + j = const và i - j = const, đường chéo thứ nhất được ghi nhận bởi dãy biến bj, đường chéo thứ 2 được ghi nhận bởi dãy biến cj với qui ước nếu đường chéo nào còn trống thì giá trị tương ứng của nó là 1 ngược lại

là 0 Như vậy, cột j được chấp nhận khi cả 3 biến aj, bi+j, ci+j đều có giá trị 1 Các biến này phải được khởi đầu giá trị 1 trước đó, gán lại giá trị 0 khi xếp xong quân hậu thứ i và trả lại giá trị 1 khi đưa ra kết quả

#include <stdio.h>

#include <stdlib.h>

#include <conio.h>

#include <dos.h>

void hoanghau(int);

void inloigiai(int loigiai[]);

FILE *fp;

Trang 12

int A[N], B[D], C[D], loigiai[N];

int soloigiai =0;

void hoanghau(int i){

int j;

for (j=0; j<N;j++){

if (A[j] && B[i-j+SG] && C[i+j] ) {

loigiai[i]=j;

A[j]=FALSE;

B[i-j+SG]=FALSE;

C[i+j]=FALSE;

if (i==N-1){

soloigiai++;

inloigiai(loigiai); delay(500);

} else

hoanghau(i+1); A[j]=TRUE;

B[i-j+SG]=TRUE;

C[i+j]=TRUE;

} }

}

void inloigiai(int *loigiai){

int j;

printf("\n Lời giải %3d:",soloigiai);

fprintf(fp,"\n Lời giải %3d:",soloigiai); for (j=0;j<N;j++){

printf("%3d",loigiai[j]);

fprintf(fp,"%3d",loigiai[j]);

}

}

void main(void){

int i;

clrscr();

fp=fopen("loigiai.txt","w");

for (i=0;i<N;i++)

A[i]=TRUE;

for(i=0;i<D; i++){

B[i]=TRUE;

C[i]=TRUE;

}

hoanghau(0);

fclose(fp);

}

Trang 13

Bài tốn Tháp Hà Nội (Tower of Hanoi)

Truyền thuyết 1: Một nhà toán học Pháp sang thăm Đông Dương đến một ngôi chùa cổ ở Hà Nội thấy các vị sư đang chuyển một chồng đĩa qúy gồm 64 đĩa với kích thước khác nhau từ cột A sang cột C theo cách:

- Mỗi lần chỉ chuyển 1 đĩa

- Khi chuyển có thể dùng cột trung gian B

- Trong suốt qúa trình chuyển các chồng đĩa ở các cột luôn được xếp đúng (đĩa có kích thước bé được đặt trên đĩa có kích thước lớn )

Khi được hỏi các vị sư cho biết khi chuyển xong chồng đĩa thì đến ngày tận thế !

Truyền thuyết 2: Lúc thế giới hình thành, trong ngơi đền thờ Brahma cĩ một chồng 64 cái đĩa Mỗi ngày, cĩ một thầy tu di chuyển một đĩa Đến khi hết đĩa thì đĩ là ngày tận thế

Như sẽ chỉ ra sau này với chồng gồm n đĩa cần 2n- 1 lần chuyển cơ bản (chuyển 1 đĩa ) 2n

Giả sử thời gian để chuyển 1 đỉa là t giây thì thời gian để chuyển xong chồng 64 đĩa sẽ là:

T = ( 264-1 ) * t giây = 11.84*1019*t giây

Với t = 1/100 giây thì T =5.8*109 năm = 5.8 tỷ năm

Ta có thể tìm thấy giải thuật (dãy các thao tác cơ bản ) cho bài toán một cách dễ dàng ứng với trường hợp chồng đĩa gồm 0, 1, 2, 3 đĩa Với chồng 4 đĩa giải thuật bài toán đã trở nên phức tạp Tuy nhiên giải thuật của bài toán lại được tìm thấy rất dễ dàng nhanh chóng khi ta khái quát số đĩa là n bất kỳ và nhìn bài toán bằng quan niệm đệ quy

a) Thông số hóa bài toán

Xét bài toán ở mức tổng quát nhất : chuyển n (n>=0) đĩa từ cột X sang cột Z lấy cột Y làm trung gian

Ta gọi giải thuật giải bài toán ở mức tổng quát là thủ tục THN(n ,X ,Y,Z) chứa 4 thông số n,X,Y,Z ; n thuộc tập số tự nhiên N (kiểu nguyên không dấu ); X ,Y,Z thuộc tập các ký tự (kiểu ký tự )

Bài toán cổ ở trên sẻ được thực hiện bằng lời gọi THN(64,A,B,C)

Dễ thấy rằng : trong 4 thông số của bài toán thì thông số n là thông số quyết định độ phức tạp của bài toán ( n càng lớn thì số thao tác chuyển đỉa càng nhiều và thứ tự thực hiện chúng càng khó hình dung ) , n là thông số điều khiển

b) Trường hợp suy biến và cách giải

Với n =1 bài toán tổng quát suy biến thành bài toán đơn giản THN (1,X,Y,Z) : tìm dãy thao tác để chuyển chồng 1 đĩa từ cột X sang cột Z lấy cột Y làm trung gian Giải thuật giải bài toán THN (1,X,Y,Z) là thực hiện chỉ 1 thao tác cơ bản : Chuyển 1 đĩa từ X sang Z ( ký hiệu là Move (X , Z) ) THN(1,X,Y,Z) ≡ { Move( X, Z ) }

Chú ý : Hoàn toàn tương tự ta cũng có thể quan niện trường hợp suy biến là trường hợp n=

0 tương ứng với bài toán THN(0,X,Y,Z) : chuyển 0 đĩa từ X sang Z lấy Y làm trung gian mà giải thuật tương ứng là không làm gì cả ( thực hiện thao tác rỗng )

THN(0,X,Y,Z) ≡ {φ }

c) Phân rã bài toán :

Ta có thể phần rã bài toán TH N (k,X,Y,Z) : chuyển k đĩa từ cột X sang cột Z lấy cột Y làm trung gian thành dãy tuần tự 3 công việc sau :

Trang 14

+ Chuyển (k -1) đĩa từ cột X sang cột Y lấy cột Z làm trung gian :

THN (k -1,X,Z,Y) (bài toán THN với n = k-1,X= X , Y = Z , Z = Y )

+ Chuyển 1 đĩa từ cột X sang cột Z : Move ( X, Z ) (thao tác cơ bản )

+ Chuyển (k - 1 ) đĩa từ cột Y sang cột Z lấy cột X làm trung gian :

THN( k -1,Y,X,Z) ( bài toán THN với n = k-1 , X = Y , Y = X , Z = Z )

Vậy giải thuật trong trường hợp tổng quát (n > 1) là :

THN(n,X,Y,Z) ≡ {

THN (n -1,X,Z,Y) ; Move ( X, Z ) ; THN (n -1,Y,X,Z) ; }

Với n đĩa thì cần bao nhiêu bước chuyển 1 đĩa? Thực chất trong thủ tục THN các lệnh gọi đệ qui chỉ nhằm sắp sếp trình tự các thao tác chuyển 1 đĩa

Số lần chuyển 1 đĩa được thực hiện là đặc trưng cho độ phức tạp của giải thuật

Với n đĩa , gọi f(n) là số các thao tác chuyển _một_đĩa

f(1) =1 f(n) = 2f(n -1) + 1 với n > 0

Do đo ù : f(n) = 1+ 2 + 2 2 + + 2 n-1 = 2 n - 1

Để chuyển 64 đĩa cần 2 64 - 1 bước hay xấp xỉ 10 20 bước Cần khoảng 10 triệu năm với một máy tính nhanh nhất hiện nay để làm việc này

Hàm thực hiện:

void THN(int n, char X,Y,Z){

if(n > 0) {

THN(n -1,X,Z,Y ) ; Move ( X , Z ) ; THN(n - 1,Y,X,Z ) ; }

return ;

}

hoặc :

void THN( int n , char X,Y,Z) {

if(n = = 1) Move ( X , Z ) ;

else {

THN(n -1,X,Z,Y ) ; Move ( X, Z ) ; THN(n - 1,Y,X,Z ) ; }

return ;

}

Trang 15

Bài toán tìm cặp điểm gần nhất trong mặt phẳng (Closest

Pair)

Trang 16

Bài tập

Phần 1: Mảng và chuỗi ký tự

1 Nhập vào một dãy số nguyên gồm n phần tử Tìm cặp phần tử có tổng đúng bằng k (k nhập từ bàn phím)

2 Nhập dãy n số (n ≤ 1000) Xác định đường chạy dài nhất, xuất lên màn hình vị trí phần tử đầu tiên và độ dài của đường chạy đó Đường chạy là một dãy liên tiếp các phần tử không giảm của dãy ban đầu

Ví dụ : Nhập dãy 1 4 2 3 1 2 6 8 3 5 7

Đường chạy dài nhất là : 4 4

3 Nhập dãy n số (n ≤ 1000) Xét dãy số có đối xứng không?

4 Viết chương trình nhập/ xuất một ma trận số thực n x m (n, m ≤ 100) Sắp xếp các giá trị các phần tử của ma trận không giảm theo đường zigzag

Ví dụ:

5 Viết chương trình nhập/ xuất một ma trận vuông số nguyên dương n x n (n≤ 100 và n lẻ) Xét ma trận có đối xứng qua:

a Đường chéo chính

b Theo dòng, cột

c Tâm

6 Viết chương trình nhập chuỗi ký S:

a Đếm và cho biết số lượng khoảng trắng, số lượng ký số, số lượng chữ cái latin, số lượng các ký tự khác

b Đếm và cho biết số lượng từ của chuỗi – các từ cách nhau bởi khoảng trắng

c Biến đổi chuỗi sao cho các ký tự đầu mỗi từ là ký tự in hoa, các ký tự khác in thường

2 Viết chương trình nhập chuỗi ký S, đếm và in cho biết số lượng của mỗi chữ cái latin trong chuỗi (không phân biệt chữ in hoa và chữ in thường)

7 Viết chương trình nhập 3 chuỗi ký tự S, S1, S2 Hãy tìm trên chuỗi S tất cả những lần xuất hiện của S1 và thay bằng S2

8 Một số tự nhiên là Palindrom nếu các chữ số của nó viết theo thứ tự ngược lại thì số tạo thành là chính số đó ( Ví dụ: 4884, 393) Hãy tìm: Tất cả các số tự nhiên nhỏ hơn 100 mà khi bình phương lên thì cho một Palindrom

9 Viết chương trình đảo ngược vị trí các từ trong câu Ví dụ: “KIEN AN CA” đổi thành

“CA AN KIEN”

10 Nhập một câu không quá 20 từ, mỗi từ không quá 10 ký tự Viết chương trình tách các từ trong câu và in các từ theo thứ tự Alphabet Ví dụ: “PHAN VIEN CONG NGHE THONG TIN” tách thành [PHAN], [VIEN], [CONG], [NGHE], [THONG], [TIN] và in ra: CONG NGHE PHAN THONG TIN VIEN

Phần 2: Cấu trúc

Xây dựng cấu trúc điểm, đường thẳng, hình chữ nhật, đường tròn

1 Xét vị trí tương đối của 03 điểm trên mặt phẳng

2 Xét vị trí tương đối giữa hai đoạn thẳng

3 Xét 1 điểm có nằm trong 1 : hình chữ nhật, tròn hay không

4 Xét vị trí tương đối của 1 đường thẳng và hình chữ nhật, tròn

Ngày đăng: 22/07/2014, 16:21

TỪ KHÓA LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm