| # | Bài tập | Điểm | Thời gian: | Giới hạn bộ nhớ |
|---|---|---|---|---|
| 1 | JOI 2011 - Guess Them All | 100 (p) | 2.0s | 64M |
| 2 | JOI 2011 - Keycards | 100 (p) | 1.0s | 64M |
| 3 | JOI 2011 - Shiritori | 100 (p) | 5.0s | 64M |
Bạn đang chơi trò đoán số với JOI-chan. Trước tiên, JOI-chan sắp xếp mỗi số nguyên từ \(1\) đến \(N\) đúng một lần theo một thứ tự nào đó để tạo thành một dãy số. Gọi dãy này là đáp án. Bạn được thực hiện nhiều nhất \(L\) lần dự đoán; bạn thắng nếu đoán đúng đáp án trong không quá \(L\) lần.
Trong mỗi lần dự đoán, bạn đưa cho JOI-chan một dãy gồm \(N\) số nguyên từ \(1\) đến \(N\). Dãy dự đoán được phép chứa các số nguyên trùng nhau. Sau mỗi lần dự đoán, bạn được biết có bao nhiêu vị trí mà dãy dự đoán trùng với đáp án.
Hãy viết chương trình đoán đúng dãy đáp án trong số lần dự đoán cho phép. Đây là bài toán tương tác: chương trình trao đổi với hệ thống chấm qua đầu vào chuẩn và đầu ra chuẩn.
Khi bắt đầu, đọc một dòng từ đầu vào chuẩn chứa số nguyên \(N\).
Giới hạn \(L\) được quy định trong phần Phân nhóm; đầu vào ban đầu chỉ chứa \(N\). Các dữ liệu nhận được sau đó là phản hồi cho từng dự đoán, theo giao thức dưới đây.
Các dự đoán được gửi qua đầu ra chuẩn theo giao thức dưới đây.
Sau khi đọc \(N\), chương trình phải luân phiên gửi một dự đoán ra đầu ra chuẩn và đọc một phản hồi từ đầu vào chuẩn:
Để tránh việc đọc đầu vào bị chặn do dữ liệu đầu ra còn nằm trong bộ đệm, cần đẩy dữ liệu đầu ra trước khi chờ phản hồi. Gọi fflush(stdout); hoặc thực hiện thao tác tương đương trước khi đọc.
Đoạn chương trình C sau minh họa cách trao đổi với hệ thống chấm:
#include <stdio.h>
int main(void) {
int i, N, ret;
scanf("%d", &N);
for (;;) {
for (i = 1; i <= N; i++) {
printf("%d\n", i); // Gui du doan
}
fflush(stdout); // Day dau ra truoc khi doc phan hoi
scanf("%d", &ret); // Doc phan hoi cua he thong cham
if (ret == N) break;
}
return 0;
}
Đây là chương trình minh họa giao tiếp; nó lặp lại dự đoán \(1,2,\ldots,N\).
Theo tài liệu kỹ thuật của kỳ thi gốc:
long long, với định dạng %lld khi dùng scanf hoặc printf.scanf/printf thay cho cin/cout do tốc độ vào/ra trên hệ thống thi gốc.Bài có tổng cộng \(100\) điểm, gồm \(10\) bộ dữ liệu, mỗi bộ \(10\) điểm.
Cột Input là dữ liệu hệ thống chấm gửi cho chương trình; cột Output là dữ liệu chương trình gửi cho hệ thống chấm. Mỗi số nằm trên một dòng riêng. Các nhãn cột chỉ dùng để trình bày, không thuộc dữ liệu giao tiếp.
Ví dụ 1
3
1
0
3
3
2
1
1
2
3
2
3
1
Trong ví dụ này, chương trình đọc \(N=3\), rồi lần lượt dự đoán \((3,2,1)\), \((1,2,3)\) và \((2,3,1)\). Các phản hồi tương ứng là \(1\), \(0\) và \(3\). Chương trình đoán đúng sau \(3\) lần dự đoán và kết thúc khi nhận được phản hồi cuối cùng.
Chìa khóa phòng ở khu lưu trú của cơ sở tổ chức trại xuân JOI là những tấm thẻ có đục lỗ. Có \(N\) vị trí có thể đục lỗ. Người ta đã tạo ra \(2^N\) chiếc chìa khóa khác nhau, tương ứng với tất cả các cách chọn những vị trí được đục lỗ.
Bạn nhận được một tập gồm từ \(1\) đến \(2^N\) chiếc chìa khóa để dùng trong trại xuân JOI. Khi xếp chồng các thẻ sao cho các vị trí có thể đục lỗ trùng nhau, bạn nhận thấy có đúng \(K\) vị trí mà tất cả các thẻ nhận được đều có lỗ.
Có bao nhiêu cách chọn tập chìa khóa nhận được để điều này xảy ra? Cho \(N\) và \(K\), hãy tính số cách đó lấy phần dư khi chia cho \(1\,000\,000\,007\), là một số nguyên tố.
Đọc từ đầu vào chuẩn một dòng chứa hai số nguyên \(N,K\), cách nhau bởi dấu cách.
In ra đầu ra chuẩn một dòng chứa số cách chọn tập chìa khóa thỏa mãn điều kiện, lấy phần dư khi chia cho \(1\,000\,000\,007\).
Theo tài liệu kỹ thuật của kỳ thi gốc:
long long, với định dạng %lld khi dùng scanf hoặc printf.scanf/printf thay cho cin/cout do tốc độ vào/ra trên hệ thống thi gốc.Bài có tổng cộng \(100\) điểm, gồm \(2\) bộ dữ liệu, mỗi bộ \(5\) điểm, và \(9\) bộ dữ liệu, mỗi bộ \(10\) điểm. Các tỉ lệ sau là tỉ lệ tích lũy:
Ví dụ 1
3 3
1
Khi \(N=3\), có tất cả \(8\) chiếc chìa khóa. Ta đặt tên cho chúng theo hình dưới đây; cột bên trái mô tả các lỗ trên thẻ, cột bên phải là tên thẻ.
Thẻ không có lỗ được ký hiệu là \(\phi\); ba thẻ có một lỗ được gọi là \(A\), \(B\), \(C\); các thẻ có hai lỗ là \(AB\), \(BC\), \(AC\); thẻ có cả ba lỗ là \(ABC\).
Nếu chỉ nhận một thẻ \(ABC\), số vị trí mà tất cả các thẻ nhận được đều có lỗ là \(3\). Không có cách nhận thẻ nào khác cho đúng \(3\) vị trí như vậy. Do đó, chỉ có \(1\) cách thỏa mãn điều kiện.
Ví dụ 2
3 2
6
Nếu nhận hai thẻ \(\{AB,ABC\}\), có đúng \(2\) vị trí mà tất cả các thẻ nhận được đều có lỗ. Tương tự, các cách nhận \(\{AC,ABC\}\), \(\{BC,ABC\}\), \(\{AB\}\), \(\{AC\}\) và \(\{BC\}\) cũng có đúng \(2\) vị trí như vậy.
Ví dụ 3
3 1
30
Có \(30\) cách nhận thẻ thỏa mãn điều kiện, chẳng hạn \(\{A\}\), \(\{A,AB\}\), \(\{A,AC\}\), \(\{A,ABC\}\), \(\{A,AB,AC\}\), \(\{A,AB,ABC\}\), \(\{A,AC,ABC\}\), \(\{A,AB,AC,ABC\}\), \(\{AB,AC\}\) và \(\{AB,AC,ABC\}\).
Ví dụ 4
3 0
218
Đất nước JOI sử dụng \(100\) ký tự khác nhau. Vì khó biểu diễn trực tiếp các ký tự này trên máy tính, người ta dùng cách viết thay thế sau:
00 01 02 03 04 05 06 07 08 09
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59
60 61 62 63 64 65 66 67 68 69
70 71 72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87 88 89
90 91 92 93 94 95 96 97 98 99
Như vậy, mỗi ký tự được biểu diễn bằng hai chữ số, với \(10\times10\) khả năng. Từ điển của đất nước JOI sắp xếp các từ theo thứ tự ký tự trong bảng này: ký tự ở hàng phía trên đứng trước; trong cùng một hàng, ký tự nằm bên trái đứng trước.
Hiện nay, trò chơi nối từ shiritori đang rất thịnh hành ở đất nước JOI. Người chơi lần lượt nói một từ bắt đầu bằng ký tự cuối cùng của từ mà người trước vừa nói. Không được dùng lại một từ đã được nói.
Một ngày nọ, bạn chơi “shiritori 5” cùng bạn bè. Ngoài các quy tắc thông thường của shiritori, trò chơi này yêu cầu mọi từ được sử dụng đều phải có đúng \(5\) ký tự. Bạn đã ghi lại trên máy tính danh sách \(N\) từ được nói, nhưng vô tình sắp xếp lại danh sách. Hãy khôi phục diễn biến của trò chơi “shiritori 5” từ danh sách đó.
Đọc từ đầu vào chuẩn:
Nếu không thể tạo thành một trò chơi “shiritori 5” sử dụng tất cả \(N\) từ đã cho, in ra đầu ra chuẩn một dòng chứa impossible.
Nếu có thể, in \(N\) từ theo thứ tự được nói, mỗi từ trên một dòng và mỗi từ được dùng đúng một lần. Nếu có nhiều thứ tự hợp lệ, chọn thứ tự theo các ưu tiên sau:
00 đến 99.Theo tài liệu kỹ thuật của kỳ thi gốc:
long long, với định dạng %lld khi dùng scanf hoặc printf.scanf/printf thay cho cin/cout do tốc độ vào/ra trên hệ thống thi gốc.Bài có tổng cộng \(100\) điểm, gồm \(20\) bộ dữ liệu, mỗi bộ \(5\) điểm. Các tỉ lệ dưới đây mô tả những tập dữ liệu có thể giao nhau:
00 đến 19.00 đến 19, vừa thỏa mãn \(N\le1000\).00 đến 19, hoặc \(N\le1000\).Ví dụ 1
5
0000010201
0102030403
0104050603
0206070801
0308090002
0000010201
0102030403
0308090002
0206070801
0104050603
Có hai thứ tự “shiritori 5” hợp lệ:
0000010201 → 0102030403 → 0308090002 → 0206070801 → 0104050603.0000010201 → 0104050603 → 0308090002 → 0206070801 → 0102030403.Từ thứ nhất giống nhau. Khi so sánh từ thứ hai theo thứ tự từ điển, phương án đầu tiên được chọn để in ra.
Ví dụ 2
4
9600000098
9700000099
9800000099
9900000098
impossible
Không tồn tại thứ tự “shiritori 5” hợp lệ cho ví dụ này.
Ví dụ 3
12
0114090401
0214051905
0304141219
0510031717
0703050011
1102190101
1108040907
1110090702
1313071203
1707120711
1902090011
1909121313
1909121313
1313071203
0304141219
1902090011
1108040907
0703050011
1110090702
0214051905
0510031717
1707120711
1102190101
0114090401