Kỳ thi học sinh giỏi quốc gia - Lớp 12 PTTH 2002-2003 Ngày thi thứ nhất: Hãy lập trình giải các bài toán sau: Bài 1. Hướng đi: Tên chương trình : WHATDIR.PAS Rô bốt được lập trình để ghi nhận tự động đường di chuyển của mình. Rô bốt có thể rẽ trái −thay đổi hướng đi 90 0 về phía trái so với hướng chuyển động hiện tại, rẽ phải − thay đổi hướng đi 90 0 về phía phải so với hướng chuyển động hiện tại hoặc giữ nguyên hướng đi hiện tại. Đường đi được ghi nhận dưới dạng xâu các ký tự L, R và C. Trong đó, L cho biết rô bốt rẽ trái và đi theo hướng đó một đơn vị độ dài (gọi tắt là một bước ), R − rẽ phải và đi một bước, C − tiếp tục đi một bước theo hướng hiện tại. Ví dụ, ban đầu rô bốt đang hướng về phía Đông. Xâu ký tự thể hiện đường đi nêu ở hình 2 sẽ là LRLRLLC. Để tiện lưu trữ, xâu này sẽ được rô bốt lưu dưới dạng xâu nén S: nếu một ký tự lặp lại nhiều lần liên tiếp nhau thì nó được ghi một lần với hệ số lặp ở trước, nếu nhóm ký tự lặp lại nhiều lần liên tiếp nhau, thì nó được đặt trong dấu ngoặc tròn với hệ số lặp ở trước. Như vậy, xâu S thể hiện đường đi ở hình 2 sẽ là 2(LR)2LC. Hệ số lặp, nếu có − là số nguyên ở hệ thập phân, lớn hơn 1 và nhỏ hơn 1000. Xâu S có độ dài không vượt quá 200. Định kỳ, sau một khoảng thời gian nhất định, rô bốt dừng lại, truyền xâu S ghi nhận đường đã đi của mình về trung tâm điều khiển và chờ đợi lệnh điều khiển tiếp theo. Để có thể ra chỉ thị mới, người ta cần biết rô bốt đang hướng về phía nào (Đông, Tây, Nam hay Bắc). Hướng được mã hoá bằng một ký tự in hoa: E − Đông, W − Tây, S − Nam, N −Bắc. Yêu cầu: Biết hướng ban đầu của rô bốt và xâu S mô tả đường đã đi. Hãy xác định, rô bốt đang hướng về phía nào? Dữ liệu: Vào từ file văn bản WHATDIR.INP có nội dung như sau: Dòng đầu tiên chứa một ký tự cho biết hướng ban đầu của rô bốt, Dòng thứ 2 chứa xâu S mô tả đường đi. Kết quả: Đưa ra file văn bản WHATDIR.OUT một ký tự duy nhất cho biết hướng của rô bốt ở cuối đường đi. Ví dụ : Bài 2: Truyền tin Tên file chương trình: TRANSMIT.PAS Một máy truyền tin có khả năng truyền mỗi lần một thông điệp dưới dạng một chuỗi nhị phân gồm N bit, các bit được truyền song song, mỗi bit sẽ được truyền trên một kênh truyền riêng biệt đến máy thu. Trong trạng thái bình thường, chuỗi nhận được tại máy thu giống hoàn toàn chuỗi đã được phát. Thật không may, do sơ xuất khi lắp đặt máy thu, đã có một sự đảo lộn các kênh truyền. Hậu quả là chuỗi nhận được tại máy thu lại là một hoán vị của chuỗi ban đầu. Trong hoàn cảnh hiện tại, vì cần phải sử dụng gấp các thiết bị truyền tin này phục vụ cho công việc, thời gian lại không cho phép để sửa chữa hoặc thay thế, nên tổ kỹ thuật buộc phải tìm cách phát hiện được sự hoán chuyển các kênh đã xảy ra để có thể khôi phục đúng những thông điệp đã gửi. Rất may, khi lắp đặt, người ta đã thử phát M chuỗi và ghi lại M chuỗi tương ứng nhận được tại máy thu. Yêu cầu: Là chuyên viên tin học, bạn hãy viết chương trình giúp tổ kỹ thuật chỉ ra sự tương ứng giữa các bit trong chuỗi phát đi và chuỗi nhận được nơi máy thu. Điều này nghĩa là, dựa trên M cặp chuỗi phát và thu tương ứng, bạn phải chỉ ra bộ hoán vị a 1 , a 2 ,…, a N , trong đó cho biết bit thứ a i trong thông điệp gửi đi đã chuyển thành bit thứ i trong thông điệp nhận được. Dữ liệu: Dữ liệu vào cho trong file văn bản có tên TRANSMIT.INP có cấu trúc như sau: Dòng đầu chứa 2 số nguyên N, M (1 < N ≤ 100, 0 < M ≤ 10000) cách nhau bởi dấu cách cho biết số lượng bit trong mỗi thông điệp và số lượng thông điệp đã phát thử. Mỗi dòng trong M dòng tiếp theo chứa hai chuỗi bit. Mỗi chuỗi là một dãy liên tiếp N số 0 hoặc 1. Hai chuỗi cách nhau bởi một dấu cách. Chuỗi đầu là chuỗi phát đi và chuỗi thứ hai là chuỗi tương ứng nhận được tại máy thu. Kết quả: Kết quả ghi ra file văn bản có tên TRANSMIT.OUT với một dòng duy nhất có nội dung như sau: Nếu với M cặp thông điệp đã cho có thể xác định duy nhất bộ hoán vị a 1 , a 2 , …, a N thì file kết quả sẽ chứa N số nguyên cho biết bộ hoán vị này. Các số trên cùng một dòng cách nhau bởi một dấu cách, Ngược lại thì file kết quả chỉ chứa duy nhất một số -1. Ví dụ: Ngày thi thứ hai: Bài 3. Đếm Tên chương trình : COUNT.PAS Chương trình COUNT trên ngôn ngữ PASCAL có chứa khai báo: VAR D: ARRAY[1 16000] OF BYTE; N: INTEGER; Khai báo này xác định 2 biến D và N dùng chung trong tất cả các thủ tục và hàm của chương trình. Chương trình này có chứa các thủ tục: Thủ tục QL được mô tả bắt đầu bằng dòng: PROCEDURE QL(K: BYTE; I,T: INTEGER); Thủ tục không tham số KTRA được mô tả bắt đầu bằng dòng: PROCEDURE KTRA; Nhiệm vụ của thủ tục QL: Khi K nhận giá trị 1, thủ tục sẽ gán giá trị 1 vào các phần tử D[J], với J thay đổi từ I đến I+T-1 (I+T-1 ≤ N), Khi K nhận giá trị 2, thủ tục sẽ gán giá trị 0 vào các phần tử D[J], với J thay đổi từ I đến I+T-1 ≤ N (I+T-1 ≤ N). Nhiệm vụ của thủ tục KTRA là xác định số lượng lớn nhất các phần tử liên tiếp nhau bằng 0 trong số N phần tử đầu tiên của D. Mỗi lần thực hiện, đầu tiên chương trình COUNT sinh ra giá trị N và trong suốt quá trình thực hiện chương trình COUNT giá trị N không bị thay đổi bởi bất cứ câu lệnh nào. Tiếp đến chương trình COUNT gán giá trị 0 cho mọi phần tử của D. Sau đó chương trình COUNT tạo ra hai file văn bản COUNT.INP và COUNT.OUT rỗng. Chương trình COUNT dùng 2 file COUNT.INP và COUNT.OUT để ghi biên bản thực hiện các lời gọi QL và KTRA gặp trong COUNT theo đúng trình tự thực hiện. Việc ghi biên bản thực hiện các lời gọi QL và KTRA được tiến hành như sau: Đầu tiên COUNT ghi ra file COUNT.INP số nguyên N trên dòng thứ nhất bằng lệnh WRITELN. Sau đó, mỗi khi gặp lời gọi thủ tục QL, trước khi thực hiện thủ tục, chương trình sẽ ghi tiếp ra file COUNT.INP ba giá trị nguyên dương K, I và T, ghi trên một dòng bằng lệnh WRITELN, các số cách nhau một dấu cách. Khi gặp lời gọi KTRA, chương trình COUNT sẽ ghi tiếp ra file COUNT.INP số 3 trên một dòng bằng lệnh WRITELN và ghi kết quả thực hiện KTRA ra file văn bản COUNT.OUT dưới dạng số nguyên, ghi trên một dòng cũng bằng lệnh WRITELN. Mảng D dùng để đánh dấu. Trong chương trình COUNT, ngoài thủ tục QL, không có câu lệnh nào khác thay đổi giá trị các phần tử của D. Chương trình COUNT đã được hiệu chỉnh, sửa hết các lỗi và đã được thực hiện. Dĩ nhiên, ngoài các lời gọi QL và KTRA, COUNT còn làm nhiều việc khác và vì vậy thời gian thực hiện là khá lớn. Một lần, sau khi thực hiện chương trình COUNT, tác giả chương trình tiến hành dọn dẹp đĩa, xoá các file trung gian không cần thiết và sơ ý xoá nhầm luôn file COUNT.OUT ! Thực hiện lại COUNT thì mất quá nhiều thời gian. Sau những phút hoang mang ban ban đầu, anh ta thấy có thể khôi phục lại file COUNT.OUT dựa trên cơ sở của file COUNT.INP, chỉ có điều phải lập trình tốt, vì kích thước của COUNT.INP cho thấy nó có thể chứa tới cỡ 200000 dòng. Yêu cầu : Khôi phục file COUNT.OUT dựa trên nội dung của file COUNT.INP. Dữ liệu : Dữ liệu vào từ file văn bản COUNT.INP - kết quả của chương trình COUNT. Kết quả : Kết quả xuất ra file văn bản COUNT.OUT, theo đúng quy cách và nội dung như do chương trình COUNT đưa ra. Ví dụ : Bài 4. Thuê giầy Tên file chương trình: SHOES.PAS Một hiệu cho thuê giầy ở một sân vận động có M đôi giầy, đôi giầy thứ i có kích thước si, i = 1, 2, …, M. Có một nhóm gồm N (N ≤ M) bạn học sinh đến hiệu thuê giầy để tập chạy tại sân vận động. Học sinh j muốn thuê đôi giầy có kích thước hj, j=1, 2, …, N. Mọi việc sẽ rất tốt đẹp nếu như mỗi bạn học sinh đều thuê được đôi giầy đúng kích thước mình mong muốn. Trong trường hợp điều đó là không thể thực hiện được, nhóm học sinh này muốn tìm cách chọn N đôi giầy trong số M đôi giầy của hiệu giầy và phân bố cho các thành viên của nhóm sao cho tổng giá trị tuyệt đối của các chênh lệch giữa kích thước của đôi giầy nhận được và kích thước của đôi giầy muốn thuê của các bạn trong nhóm là nhỏ nhất. Tổng này được gọi là độ lệch của cách thuê giầy. Như vậy, nếu học sinh j nhận được đôi giầy pj (j= 1, 2, … , N) thì độ lệch của cách thuê giầy này là: Yêu cầu: Hãy giúp nhóm học sinh tìm cách thuê giầy với độ lệch nhỏ nhất. Dữ liệu: Vào từ file văn bản SHOES.INP, trong đó: Dòng đầu tiên chứa hai số nguyên dương M, N (1 ≤ N ≤ M ≤ 100), Dòng thứ hai chứa các số nguyên dương s 1 , s 2 , … , s M , Dòng thứ ba chứa các số nguyên dương h 1 , h 2 ,… , h N . Kết quả: Ghi ra file văn bản SHOES.OUT, trong đó: Dòng thứ nhất ghi độ lệch của cách thuê giầy tìm được, Dòng thứ hai ghi N số nguyên dương, trong đó số thứ j là chỉ số của đôi giầy dành cho bạn học sinh j (j = 1, 2, … , N) theo cách thuê giầy tìm được. Ví dụ: Trong file dữ liệu vào và file kết quả, các số trên một dòng cách nhau ít nhất một dấu cách. . (N ≤ M) bạn học sinh đến hiệu thuê giầy để tập chạy tại sân vận động. Học sinh j muốn thuê đôi giầy có kích thước hj, j=1, 2, …, N. Mọi việc sẽ rất tốt đẹp nếu như mỗi bạn học sinh đều thuê. Kỳ thi học sinh giỏi quốc gia - Lớp 12 PTTH 2002 -2003 Ngày thi thứ nhất: Hãy lập trình giải các bài toán sau: Bài 1. Hướng. lệch của cách thuê giầy. Như vậy, nếu học sinh j nhận được đôi giầy pj (j= 1, 2, … , N) thì độ lệch của cách thuê giầy này là: Yêu cầu: Hãy giúp nhóm học sinh tìm cách thuê giầy với độ lệch