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

Phương pháp thử sai trong lập trình

38 1,3K 2

Đ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 38
Dung lượng 1,04 MB

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

Nội dung

huyên đề này trình bày phương pháp Thử sai. Cũng như các phương pháp khác như Tham ăn, Chia để trị và Quy hoạch động, đây là chiến lược tổng quát. Phương pháp này chỉ là chiến lược, có tính định hướng tìm thuật toán. Việc áp dụng phương pháp để tìm ra thuật toán cho một bài toán cụ thể còn đòi hỏi nhiều sáng tạo. Trong chuyên đề này, ngoài phần trình bày về phương pháp, chuyên đề còn có những ví dụ cụ thể, cùng với thuật giải và cài đặt, để có cái nhìn chi tiết từ việc thiết kế giải thuật đến xây dựng chương trình. 1. Phương pháp thử sai Trong nhiều bài toán, việc tìm nghiệm có thể quy về việc tìm vector hữu hạn ( ), trong đó (độ dài vector) có thể xác định trước hoặc không. Vector cần tìm phải thỏa mãn một số điều kiện tùy thuộc vào yêu cầu của bài toán. Các thành phần được chọn ra từ tập hữu hạn . Tuỳ vào mục đích bài toán, có thể phải tìm một nghiệm, tìm tất cả nghiệm hoặc đếm số nghiệm. Một suy nghĩ rất tự nhiên để giải quyết bài toán là: lần lượt liệt kê cả các khả năng của nghiệm (theo dạng vector), với mỗi khả năng tiến hành kiểm tra khả năng đó có là nghiệm không? (có thỏa mãn các yêu cầu của bài toán hay không?) Hướng giải quyết như vậy ta gọi là thử sai. Bài toán MẬT KHẨU Một xâu ký tự được gọi là mật khẩu “an toàn” nếu xâu có độ dài ít nhất bằng 6 và xâu chứa ít nhất một chữ cái in hoa ( ), một chữ cái thường ( ), một chữ số ( ). Ví dụ, , là hai mật khẩu “an toàn”, còn đều không phải là mật khẩu “an toàn”. Một lần, Bình nhìn thấy một xâu , chỉ gồm các loại ký tự: chữ cái in hoa, chữ cái thường và chữ số. Bình muốn tự kiểm tra khả năng đoán nhận mật khẩu bằng cách đếm xem có bao nhiêu cặp chỉ số ( ) thỏa mãn điều kiện: ( ) và xâu con gồm các ký tự liên tiếp từ đến của là mật khẩu “an toàn”. Bài toán DÂY DẪN Cho đoạn dây điện ( ). Đoạn dây thứ có độ dài cm ( ). Cần phải cắt các đoạn đã cho thành các đoạn sao cho có được đoạn dây bằng nhau có độ dài nguyên. Có thể không cần cắt hết các đoạn dây đã cho. Mỗi đoạn dây bị cắt có thể có phần còn thừa khác 0. Yêu cầu: Xác định độ dài lớn nhất của đoạn dây có thể nhận được. Nếu không có cách cắt thì đưa ra số 0. Dữ liệu: Vào từ file văn bản WIRES.INP có dạng  Dòng đầu tiên chứa hai số nguyên  Dòng thứ trong dòng sau chứa số nguyên . Kết quả: Đưa ra file văn bản WIRES.OUT, kết quả trên một dòng dưới dạng số nguyên. Ví dụ: Quay lui vét cạn Nếu vector nghiệm đơn giản ta có thể dùng các vòng lặp để liệt kê. Tuy nhiên, trong một số trường hợp vector nghiệm phức tạp thì ta thường liệt kê bằng thủ tục quay lui vét cạn. Xét bài toán 8 quân hậu. Cần đặt 8 quân hậu vào bàn cờ vua , sao cho chúng không tấn công nhau, tức là không có hai quân hậu nào cùng hàng, cùng cột hoặc cùng đường chéo. Ví dụ: hình bên là một cách đặt hậu thỏa mãn yêu cầu bài toán, các ô được tô màu là vị trí đặt hậu. Xác định vector nghiệm: Do các quân hậu phải nằm trên các hàng khác nhau, ta đánh số các quân hậu từ 1 đến 8, quân hậu i là quân hậu nằm trên hàng thứ i (i=1,2,…,8). Gọi là cột mà quân hậu i đứng. Như vậy nghiệm của bài toán là vector ( ), trong đó , tức là được chọn từ tập +. Vector ( ) là nghiệm nếu và hai ô ( ) ( ) không nằm trên cùng một đường chéo. Ví dụ: (1,5,8,6,3,7,2,4) là một nghiệm. Quay lui vét cạn Tư tưởng của phương pháp quay lui vét cạn như sau: Ta xây dựng vector nghiệm dần từng bước, bắt đầu từ vector không ( ). Thành phần đầu tiên được chọn ra từ tập . Giả sử đã chọn được các thành phần thì từ các điều kiện của bài toán ta xác định được tập (các ứng cử viên có thể chọn làm thành phần , là tập con của ). Chọn một phần tử từ ta mở rộng nghiệm được . Lặp lại quá trình trên để tiếp tục mở rộng nghiệm. Nếu không thể chọn được thành phần ( rỗng) thì ta quay lại chọn một phần tử khác của cho . Nếu không còn một phần tử nào khác của ta quay lại chọn một phần tử khác của làm và cứ thế tiếp tục. Trong quá trình mở rộng nghiệm, ta phải kiểm tra nghiệm đang xây dựng đã là nghiệm của bài toán chưa. Nếu chỉ cần tìm một nghiệm thì khi gặp nghiệm ta dừng lại. Còn nếu cần tìm tất cả các nghiệm thì quá trình chỉ dừng lại khi tất cả các khả năng lựa chọn của các thành phần của vector nghiệm đã bị vét cạn. Lược đồ tổng quát của thuật toán quay lui vét cạn c Tổ hợp Một tổ hợp chập k của n là một tập con k phần tử của tập n phần tử. Chẳng hạn tập {1,2,3,4} có các tổ hợp chập 2 là: {1,2}, {1,3, {1,4, {2,3}, {2,4}, {3,4} Vì trong tập hợp các phần tử không phân biệt thứ tự nên tập {1,2} cũng là tập {2,1}, do đó, ta coi chúng chỉ là một tổ hợp. Bài toán: Hãy xác định tất cả các tổ hợp chập k của tập n phần tử . Để đơn giản ta chỉ xét bài toán tìm các tổ hợp của tập các số nguyên từ 1 đến n. Đối với một tập hữu hạn bất kì, bằng cách đánh số thứ tự của các phần tử, ta cũng đưa được về bài toán đối với tập các số nguyên từ 1 đến n. Nghiệm của bài toán tìm các tổ hợp chập k của n phần tử phải thoả mãn các điều kiện sau: Là một vector ( ) lấy giá trị trong tập + Ràng buộc: với mọi giá trị i từ đến (vì tập hợp không phân biệt thứ tự phần tử nên ta sắp xếp các phần tử theo thứ tự tăng dần). Ta có: 1 , do đó tập (tập các ứng cử viên được chọn làm thành phần thứ i) là từ đến ( ). Để điều này đúng cho cả trường hợp , ta thêm vào . Sau đây là chương trình hoàn chỉnh, chương trình sử dụng mô hình đệ quy để sinh tất cả các tổ hợp chập của . Chỉnh hợp không lặp Khác với chỉnh hợp lặp là các thành phần được phép lặp lại (tức là có thể giống nhau), chỉnh hợp không lặp chập k của tập n (k n) phần tử cũng là một dãy k thành phần lấy từ tập n phần tử có xét thứ tự nhưng các thành phần không được phép giống nhau. Ví dụ: Có n người, một cách chọn ra k người để xếp thành một hàng là một chỉnh hợp không lặp chập k của n. Một trường hợp đặc biệt của chỉnh hợp không lặp là hoán vị. Hoán vị của một tập n phần tử là một chỉnh hợp không lặp chập n của n. Nói một cách trực quan thì hoán vị của tập n phần tử là phép thay đổi vị trí của các ph ần tử (do đó mới gọi là hoán vị). Nghiệm của bài toán tìm các chỉnh hợp không lặp chập k của tập n số nguyên từ 1 đến n là các vector thoả mãn các điều kiện:

Trang 1

PHƯƠNG PHÁP THỬ SAI

Chuyên đề này trình bày phương pháp Thử sai Cũng như các phương pháp khác như Tham ăn, Chia để trị và Quy hoạch động, đây là chiến lược tổng quát Phương pháp này chỉ là chiến lược, có tính định hướng tìm thuật toán Việc áp dụng phương pháp để tìm ra thuật toán cho một bài toán cụ thể còn đòi hỏi nhiều sáng tạo Trong chuyên đề này, ngoài phần trình bày về phương pháp, chuyên đề còn có những ví dụ cụ thể, cùng với thuật giải và cài đặt, để có cái nhìn chi tiết từ việc thiết kế giải thuật đến xây dựng chương trình

1 Phương pháp thử sai

Trong nhiều bài toán, việc tìm nghiệm có thể quy về việc tìm vector hữu hạn ( ), trong đó (độ dài vector) có thể xác định trước hoặc không Vector cần tìm phải thỏa mãn một số điều kiện tùy thuộc vào yêu cầu của bài toán Các thành phần được chọn ra từ tập hữu hạn Tuỳ vào mục đích bài toán, có thể phải tìm một nghiệm, tìm tất cả nghiệm hoặc đếm số nghiệm

Một suy nghĩ rất tự nhiên để giải quyết bài toán là: lần lượt liệt kê cả các khả năng của nghiệm (theo dạng vector), với mỗi khả năng tiến hành kiểm tra khả năng đó có

là nghiệm không? (có thỏa mãn các yêu cầu của bài toán hay không?) Hướng giải quyết như vậy ta gọi là thử sai

Ví dụ: Cho dãy số nguyên (| | ) và một số nguyên ( ), thực hiện các yêu cầu sau:

1) Đếm số lượng dãy con liên tiếp của dãy có số phần tử lớn hơn 3

Trang 2

1) Vector nghiệm của bài toán này là ( ), trong đó ( , -)

là hai chỉ số của dãy Ta có thể thử tất cả các dãy con có độ dài lớn hơn 3 bằng cách thử tất cả các bộ ( ) với và , kiểm tra xem ∑ bằng hay không?

2) Vector nghiệm của bài toán này là ( ), trong đó ( , -) là ba chỉ số của dãy Ta có thể thử tất cả các bộ ba chỉ số với để chọn ba phần

tử có lớn nhất

3) Vector nghiệm của bài toán này là ( ), trong đó , -, nếu phần tử thứ không được chọn vào tập, nếu phần tử thứ được chọn vào tập Ta có thể thử tất cả các dãy với , -, kiểm tra xem ∑ bằng hay không?

Khi giải bài toán bằng phương pháp thử sai chúng ta thường xây dựng:

- Xây dựng thủ tục để thực hiện việc liệt kê các khả năng;

- Xây dựng hàm để kiểm tra một khả năng có thỏa mãn các điều kiện đề bài hay không?

Độ phức tạp của thuật toán theo phương pháp thử sai

Dễ dàng thấy được độ phức tạp của thuật toán theo phương pháp thử sai sẽ bằng: số khả năng thử nhân với chi phí trung bình kiểm tra một khả năng

2 Những vấn đề cần chú ý khi giải bài toán bằng phương pháp thử sai

2.1 Đoán nhận vector nghiệm

Để giải bài toán bằng phương pháp thử sai, việc đầu tiên phải làm là phải xác định được vector nghiệm, cụ thể phải xác định: vector nghiệm gồm bao nhiêu thành phần (ý nghĩa mỗi thành phần), miền giá trị của từng thành phần và các ràng buộc giữa các thành phần Đây là công việc quan trọng mang ý nghĩa quyết định đến việc giải quyết bài toán

2.2 Giảm thiểu số trường hợp phải thử, giảm thiểu chi phí kiểm tra

Trang 3

Quan sát cách tính độ phức tạp thuật toán theo phương pháp thử sai (độ phức tạp của thuật toán theo phương pháp thử sai bằng số khả năng thử nhân với chi phí trung bình kiểm tra một khả năng) ta nhận thấy, để giảm độ phức tạp thuật toán ta

có thể giảm thiểu số khả năng phải thử hoặc giảm chi phí kiểm tra

3 Một số ví dụ minh họa

3.1 Bài toán MẬT KHẨU

Một xâu ký tự được gọi là mật khẩu “an toàn” nếu xâu có độ dài ít nhất bằng 6 và

xâu chứa ít nhất một chữ cái in hoa ( ), một chữ cái thường ( ), một chữ số ( )

Ví dụ, , là hai mật khẩu “an toàn”, còn đều không phải là mật khẩu “an toàn”

Một lần, Bình nhìn thấy một xâu , chỉ gồm các loại ký tự: chữ cái in hoa, chữ cái thường và chữ số Bình muốn tự kiểm tra khả năng đoán nhận mật khẩu bằng cách đếm xem có bao nhiêu cặp chỉ số ( ) thỏa mãn điều kiện:

( ) và xâu con gồm các ký tự liên tiếp từ đến của là mật khẩu “an

toàn”.

Yêu cầu: Cho xâu , tính số lượng cặp chỉ số ( ) thỏa mãn điều kiện nêu trên

Dữ liệu: Vào từ file văn bản MATKHAU.INP gồm một dòng chứa xâu có độ dài

Trang 4

1) ;

2) Từ vị trí đến vị trí của xâu S có ký tự thuộc [„A‟ ‟Z‟]

3) Từ vị trí đến vị trí của xâu S có ký tự thuộc [„a‟ ‟z‟]

4) Từ vị trí đến vị trí của xâu S có ký tự thuộc [„0‟ ‟9‟]

Hàm isOK(x1,x2) cụ thể như sau:

function isOK(x1,x2:longint):boolean;

Trang 5

begin

isOK:= (x2-x1>=5)

and(checkHAZ(x1,x2)) and(checkLaz(x1,x2)) and(check09(x1,x2));

end;

Trong đó hàm checkHAZ(x1,x2) để kiểm tra điều kiện thứ 2 (từ vị trí đến vị trí của xâu S có ký tự thuộc [„A‟ ‟Z‟]) Hàm này trả về giá trị TRUE nếu thỏa, FALSE trong trường hợp ngược lại Tương tự checkLaz(x1,x2) để kiểm tra điều kiện thứ 3, check09(x1,x2) để kiểm tra điều kiện 4

Trang 8

Chương trình trên biến S thuộc kiểu dữ liệu ansistring (kiểu xâu ký tự cho phép độ dài lớn hơn 255) vì độ dài xâu vào lên tới 106, biến count thuộc kiểu int64 (miền giá trị -263

đến 263-1) vì số lượng có thể vượt quá kiểu longint khi độ dài xâu lên tới

106 Kiểu ansistring và int64 là hai kiểu dữ liệu có trong freepascal

Trang 9

3.1.2 Lời giải ( )

Độ phức tạp của lời giải trên là ( ) với là độ dài xâu S Để giảm độ phức tạp thì phải giảm số trường hợp phải thử hoặc giảm chi phí phần kiểm tra Dễ nhận thấy có thể giảm chi phí kiểm tra theo nhận xét sau: việc kiểm tra ( ) có thể kiểm tra nhanh trong ( ) khi đã kiểm tra ( ) Như vậy độ phức tạp thuật toán chỉ còn ( )

3.1.3 Lời giải ( )

Ta có thể giảm số trường hợp phải thử từ ( ) về ( ) bằng nhận xét sau: nếu ( ) thỏa mãn thì ( ) cũng thỏa mãn, như vậy với mỗi ta xác định nhỏ nhất để ( ) thỏa mãn thì , - đều thỏa mãn, có

vị trí thỏa mãn cho Như vậy chỉ cần thử , số lượng thỏa mãn (tương ứng với ) dễ dàng tính được

Với cách xác định như sau: * + trong đó

là vị trí nhỏ nhất lớn hơn mà từ đến có xuất hiện ký tự thuộc [„A‟ ‟Z‟], tương tự là vị trí nhỏ nhất lớn hơn mà từ đến có xuất hiện ký tự thuộc [„a‟ ‟z‟], là vị trí nhỏ nhất lớn hơn mà từ đến có xuất hiện ký tự thuộc [„0‟ ‟9‟] Việc xác định có thể xác định bằng cách chuẩn bị trước Dưới đây là chương trình hoàn chỉnh

Trang 10

for i:=1 to length(s) do

if (s[i]>='0') and (s[i]<='9') then s[i]:='1' else if (s[i]>='a')and(s[i]<='z') then s[i]:='2' else s[i]:='3';

end;

end;

procedure try;

Trang 11

var i,j :longint;

Trang 12

3.2 Bài toán DÂY DẪN

Cho đoạn dây điện ( ) Đoạn dây thứ có độ dài cm ( ) Cần phải cắt các đoạn đã cho thành các đoạn sao cho có được đoạn dây bằng nhau có độ dài nguyên Có thể không cần cắt hết các đoạn dây đã cho Mỗi đoạn dây bị cắt có thể có phần còn thừa khác 0

Yêu cầu: Xác định độ dài lớn nhất của đoạn dây có thể nhận được Nếu không có

cách cắt thì đưa ra số 0

Dữ liệu: Vào từ file văn bản WIRES.INP có dạng

 Dòng đầu tiên chứa hai số nguyên

 Dòng thứ trong dòng sau chứa số nguyên

Kết quả: Đưa ra file văn bản WIRES.OUT, kết quả trên một dòng dưới dạng số

Trang 14

Ta có nhận xét sau: nếu độ dài có thể cắt được thành đoạn thì đương nhiên ta

có thể cắt được thành đoạn có độ dài Từ nhận xét này ta sẽ giảm thiểu số trường hợp phải thử bằng thuật toán chia nhị phân, cụ thể thay thủ tục try bằng thủ tục bs_try như sau:

procedure bs_try;

Trang 15

var i,x1,lmin,lmax :longint;

Xét bài toán 8 quân hậu

Trang 16

Cần đặt 8 quân hậu vào bàn cờ vua , sao

cho chúng không tấn công nhau, tức là không có

hai quân hậu nào cùng hàng, cùng cột hoặc cùng

đường chéo

Ví dụ: hình bên là một cách đặt hậu thỏa mãn

yêu cầu bài toán, các ô được tô màu là vị trí đặt

hậu

Xác định vector nghiệm: Do các quân hậu phải nằm trên các hàng khác nhau, ta đánh số các quân hậu từ 1 đến 8, quân hậu i là quân hậu nằm trên hàng thứ i (i=1,2,…,8) Gọi là cột mà quân hậu i đứng Như vậy nghiệm của bài toán là vector ( ), trong đó , tức là được chọn từ tập

* + Vector ( ) là nghiệm nếu và hai ô ( ) ( ) không nằm trên cùng một đường chéo Ví dụ: (1,5,8,6,3,7,2,4) là một nghiệm

4.1 Quay lui vét cạn

Tư tưởng của phương pháp quay lui vét cạn như sau: Ta xây dựng vector nghiệm dần từng bước, bắt đầu từ vector không ( ) Thành phần đầu tiên được chọn ra từ tập Giả sử đã chọn được các thành phần thì từ các điều kiện của bài toán ta xác định được tập (các ứng cử viên có thể chọn làm thành phần , là tập con của ) Chọn một phần tử từ ta mở rộng nghiệm được Lặp lại quá trình trên để tiếp tục mở rộng nghiệm Nếu không thể chọn được thành phần ( rỗng) thì ta quay lại chọn một phần tử khác của cho Nếu không còn một phần tử nào khác của ta quay lại chọn một phần tử khác của làm và cứ thế tiếp tục Trong quá trình mở rộng nghiệm,

ta phải kiểm tra nghiệm đang xây dựng đã là nghiệm của bài toán chưa Nếu chỉ cần tìm một nghiệm thì khi gặp nghiệm ta dừng lại Còn nếu cần tìm tất cả các nghiệm thì quá trình chỉ dừng lại khi tất cả các khả năng lựa chọn của các thành phần của vector nghiệm đã bị vét cạn

Trang 17

Lược đồ tổng quát của thuật toán quay lui vét cạn có thể biểu diễn bởi thủ tục sau:

Trang 18

Nghiệm của bài toán tìm các tổ hợp chập k của n phần tử phải thoả mãn các điều kiện sau:

- Là một vector ( )

- lấy giá trị trong tập * +

- Ràng buộc: với mọi giá trị i từ đến (vì tập hợp không phân biệt thứ tự phần tử nên ta sắp xếp các phần tử theo thứ tự tăng dần)

Trang 19

Ta có: 1 , do đó tập (tập các ứng cử viên được chọn làm thành phần thứ i) là từ đến ( ) Để điều này đúng cho cả trường hợp , ta thêm vào

Sau đây là chương trình hoàn chỉnh, chương trình sử dụng mô hình đệ quy để sinh tất cả các tổ hợp chập của

Trang 20

( ) ( )

( )

4.2.2 Chỉnh hợp lặp

Chỉnh hợp lặp chập k của n là một dãy k thành phần, mỗi thành phần là một phần

tử của tập n phần tử, có xét đến thứ tự và không yêu cầu các thành phần khác nhau

Một ví dụ dễ thấy nhất của chỉnh hợp lặp là các dãy nhị phân Một dãy nhị phân độ

dài m là một chỉnh hợp lặp chập m của tập 2 phần tử {0,1} Các dãy nhị phân độ dài 3:

000, 001, 010, 011, 100, 101, 110, 111

Vì có xét thứ tự nên dãy 101 và dãy 011 là 2 dãy khác nhau

Như vậy, bài toán xác định tất cả các chỉnh hợp lặp chập k của tập n phần tử yêu cầu tìm các nghiệm như sau:

- Là một vector ( )

Trang 21

- lấy giá trị trong tập * +

- Không có ràng buộc nào giữa các thành phần

Chú ý là cũng như bài toán tìm tổ hợp, ta chỉ xét đối với tập n số nguyên từ 1 đến n Nếu phải tìm chỉnh hợp không phải là tập các số nguyên từ 1 đến n thì ta có thể đánh số các phần tử của tập đó để đưa về tập các số nguyên từ 1 đến n

{sử dụng một mảng x[1 n] để biểu diễn chỉnh hợp lặp Thủ tục đệ quy sau sinh tất cả chỉnh hợp lặp chập k của n}

̅

Trang 22

4.2.3 Chỉnh hợp không lặp

Khác với chỉnh hợp lặp là các thành phần được phép lặp lại (tức là có thể giống nhau), chỉnh hợp không lặp chập k của tập n (k n) phần tử cũng là một dãy k thành phần lấy từ tập n phần tử có xét thứ tự nhưng các thành phần không được phép giống nhau

Ví dụ: Có n người, một cách chọn ra k người để xếp thành một hàng là một chỉnh hợp không lặp chập k của n

Một trường hợp đặc biệt của chỉnh hợp không lặp là hoán vị Hoán vị của

một tập n phần tử là một chỉnh hợp không lặp chập n của n Nói một cách trực quan thì hoán vị của tập n phần tử là phép thay đổi vị trí của các phần tử (do đó mới gọi

là hoán vị)

Nghiệm của bài toán tìm các chỉnh hợp không lặp chập k của tập n số nguyên từ 1 đến n là các vector thoả mãn các điều kiện:

- có k thành phần: ( )

- lấy giá trị trong tập * +

- Ràng buộc: các giá trị đôi một khác nhau, tức là với mọi Sau đây là chương trình hoàn chỉnh, chương trình sử dụng mô hình đệ quy để sinh tất cả các chỉnh hợp không lặp chập của phần tử

Trang 23

end;

end;

BEGIN

write(‘Nhap n, k(k<=n):’); readln(n,k); fillchar(d,sizeof(d),0);

ChinhHopKhongLap(1);

END

Trang 24

Ví dụ về Input / Output của chương trình:

( ) ( ) ( )

4.2.4 Bài toán xếp 8 quân hậu

Trong bài toán 8 quân hậu, nghiệm của bài toán có thể biểu diễn dưới dạng vector ( ) thỏa mãn:

1) là tọa độ cột của quân hậu đang đứng ở dòng thứ

, * +

2) Các quân hậu không đứng cùng cột tức là

với

3) Có thể dễ dàng nhận ra rằng hai ô (x1,y1) và (x2,y2)

nằm trên cùng đường chéo chính (trên xuống dưới)

nếu: x1y1=x2y2, hai ô (x1,y1) và (x2,y2) nằm trên cùng đường chéo phụ (từ dưới lên trên) nếu: x1y1=x2y2, nên điều kiện để hai quân hậu xếp ở hai ô ( ) ( ) không nằm trên cùng một đường chéo là: {( ( ) ( ) ( ))

Do đó, khi đã chọn được ( ) thì được chọn phải thỏa mãn các điều kiện:

{

với mọi

Trang 25

Sau đây là chương trình đầy đủ, để liệt kê tất cả các cách xếp 8 quân hậu lên bàn cờ vua 8x8

nSk:=0;{lực lượng của tập Sk}

for xk:=1 to 8 do {thử lần lượt từng giá trị 1, 2,

…,8}

begin

ok:=true; {kiểm tra giá trị có thể chọn làm ứng

cử viên cho xk được hay không}

Trang 27

Việc xác định tập Sk có thể thực hiện đơn giản và hiệu quả hơn bằng cách sử dụng các mảng đánh dấu Cụ thể, khi ta đặt hậu i ở ô (i,x[i]), ta sẽ đánh dấu cột x[i]

(dùng một mảng đánh dấu như ở bài toán chỉnh hợp không lặp), đánh dấu đường

chéo chính (i-x[i]) và đánh dấu đường chéo phụ (i+x[i])

const n =8;

type vector =array[1 n]of integer;

var cot :array[1 n]of integer;

cheoChinh :array[1-n n-1]of integer;

cheoPhu :array[1+1 n+n]of integer;

Trang 29

Cho dãy số nguyên A gồm n phần tử a 1 ,a 2 , , a n , tìm cặp chỉ số i, j thỏa mãn:

DSEQ =|(∑ ) (∑ )| đạt giá trị lớn nhất (với 1 ≤ i < j ≤ n)

Input

- Dòng đầu là số nguyên dương n (2 ≤ n ≤ 10 5)

- Dòng tiếp theo chứa n số nguyên a 1 , a 2 , , a N (|a i |<10 9), các số cách nhau một dấu cách

Output

- Gồm một dòng chứa 2 số nguyên là DSEQ lớn nhất tìm được và số cặp chỉ

số thỏa mãn (hai số cách nhau một dấu cách)

Giả thiết N là số nguyên dương Số nguyên M là tổng của N với các chữ số của nó

N được gọi là nguồn của M Ví dụ, N = 245, khi đó M = 245 + 2 + 4 + 5 = 256 Như vậy, nguồn của 256 là 245

Không có gì đáng ngạc nhiên nếu thấy rằng có những số không có nguồn và có số lại có nhiều nguồn Ví dụ, số 216 có 2 nguồn là 198 và 207

Trang 30

Yêu cầu: Cho số nguyên M (M có không quá 100 chữ số) hãy tìm nguồn nhỏ nhất

của nó Nếu M không có nguồn thì đưa ra số 0

Dữ liệu: Vào từ file văn bản GEN.INP :

 Dòng đầu tiên chứa số nguyên T – số lượng Tests,

 T dòng sau: mỗi dòng chứa một số nguyên M

Kết quả: Đưa ra file văn bản GEN.OUT, mỗi kết quả đưa ra trên một dòng

Bài 3: Hình vuông trên mặt cầu(Olympic sinh viên)

Bằng ngôn ngữ phổ thông có thể nói hình học Riemann nghiên cứu tính chất các đối tượng hình học xác định trên mặt cầu Trong địa

lý, tọa độ một điểm trên mặt cầu thường được xác

định bằng vĩ độ và kinh độ Nhiều bài toán trong hình

học Riemann có thể giải bằng các giải thuật áp dụng

trong hình học Euclid Để ghi nhận các kết quả nghiên

cứu tìm hiểu Titan (một vệ tinh của sao Mộc) người ta

cũng tạo một mạng lưới kinh tuyến và vĩ tuyến như

đối với trái đất, chỉ khác là các vĩ tuyến được đánh số từ 0 (ở xích đạo) đến N ở bán cầu bắc và từ 0 đến –N ở bán cầu nam Trên thực tế các vĩ tuyến N và -N không

phải là đường tròn mà suy biến thành một điểm Các kinh tuyến được đánh số từ 0

đến N về phía đông và 0 đến –N về phía tây Kinh tuyến N và –N trùng nhau và

cùng tạo với kinh tuyến 0 thành một đường tròn Các kinh tuyến và vĩ tuyến chia

Hình vuô ng

1 2 3

-2 -3 -4

-1

-2

Ngày đăng: 23/11/2014, 05:02

HÌNH ẢNH LIÊN QUAN

Bài 3: Hình vuông trên mặt cầu(Olympic sinh viên) - Phương pháp thử sai trong lập trình
i 3: Hình vuông trên mặt cầu(Olympic sinh viên) (Trang 30)

TỪ KHÓA LIÊN QUAN

w