| # | Bài tập | Điểm | Thời gian: | Giới hạn bộ nhớ |
|---|---|---|---|---|
| 1 | JOI 2018 - Airline Route Map | 100 (p) | 2.0s | 1G |
| 2 | JOI 2018 - Bitaro's Party | 100 (p) | 2.0s | 512M |
| 3 | JOI 2018 - Security Gate | 100 (p) | 5.0s | 2G |
Alice sống tại Vương quốc JOI và định mời Bob, người đang sống tại Cộng hòa IOI, đến chơi. Trước đó, cô muốn gửi cho Bob bản đồ đường bay của vương quốc. JOI là quốc đảo gồm \(N\) hòn đảo, đánh số từ \(0\) đến \(N-1\), với \(M\) đường bay hai chiều. Với \(0\le i<M\), đường bay thứ \(i+1\) nối đảo \(A_i\) và đảo \(B_i\). Không có hai đường bay nối cùng một cặp đảo.
Alice phải sử dụng máy điện báo đặc biệt của vương quốc. Máy cho phép gửi một đồ thị vô hướng, nhưng số hiệu các đỉnh và các cạnh sẽ bị xáo trộn ngẫu nhiên. Cụ thể, gọi \(G\) là đồ thị Alice gửi, có \(V\) đỉnh và \(U\) cạnh:
Máy chỉ truyền được đơn đồ thị, tức đồ thị không có cạnh song song hoặc khuyên. Nói cách khác, với mọi \(0\le i<j<U\), phải có \((C_i,D_i)\ne(C_j,D_j)\) và \((C_i,D_i)\ne(D_j,C_j)\); đồng thời \(C_i\ne D_i\) với mọi \(0\le i<U\).
Alice muốn truyền bản đồ bằng đồ thị có ít đỉnh nhất. Hãy viết hai chương trình:
Trên LQDOJ, bạn nộp một tệp C++ khai báo #include "airline.h" và cài đặt cả hai hàm Alice và Bob dưới đây. Trình chấm chạy hai bản sao tách biệt của chương trình, vì vậy hai hàm không thể trao đổi dữ liệu qua biến toàn cục.
Hàm phía Alice có chữ ký:
void Alice(int N, int M, int A[], int B[]);
Hàm được gọi đúng một lần cho mỗi bộ dữ liệu. N là số đảo, M là số đường bay; A và B là hai mảng độ dài \(M\) mô tả bản đồ. Hàm Alice dùng các hàm sau để xuất đồ thị:
void InitG(int V, int U);
void MakeG(int pos, int C, int D);
InitG chỉ định số đỉnh và số cạnh của \(G\):
V phải là số nguyên từ \(1\) đến \(1500\), nếu không nhận Wrong Answer [1].U phải là số nguyên từ \(0\) đến \(V(V-1)/2\), nếu không nhận Wrong Answer [2].MakeG chỉ định cạnh số pos, nối hai đỉnh C và D, với \(V\), \(U\) là các giá trị đã truyền cho InitG:
pos phải thuộc \([0,U-1]\), nếu không nhận Wrong Answer [3].pos, nếu không nhận Wrong Answer [4].C và D phải thuộc \([0,V-1]\) và khác nhau, nếu không nhận Wrong Answer [5].Trong Alice, phải gọi InitG đúng một lần, sau đó gọi MakeG đúng \(U\) lần:
InitG lần thứ hai: Wrong Answer [6].MakeG trước InitG: Wrong Answer [7].Alice kết thúc, chưa gọi InitG hoặc số lần gọi MakeG khác \(U\): Wrong Answer [8].Alice kết thúc, đồ thị được mô tả không phải đơn đồ thị: Wrong Answer [9].Nếu lần gọi Alice bị đánh giá sai, chương trình bị kết thúc ngay.
Hàm phía Bob có chữ ký:
void Bob(int V, int U, int C[], int D[]);
Hàm được gọi đúng một lần cho mỗi bộ dữ liệu. V, U là số đỉnh và số cạnh của đồ thị nhận được; C, D là hai mảng độ dài \(U\) mô tả các cạnh. Hàm Bob dùng các hàm sau để khôi phục và xuất bản đồ:
void InitMap(int N, int M);
void MakeMap(int A, int B);
InitMap chỉ định số đảo và số đường bay đã khôi phục:
N phải bằng đúng số đảo ban đầu, nếu không nhận Wrong Answer [10].M phải bằng đúng số đường bay ban đầu, nếu không nhận Wrong Answer [11].MakeMap chỉ định một đường bay nối đảo A và đảo B, với \(N\) là giá trị đã truyền cho InitMap:
A và B phải thuộc \([0,N-1]\) và khác nhau, nếu không nhận Wrong Answer [12].Wrong Answer [13].MakeMap(A,B), nếu đã từng gọi MakeMap(A,B) hoặc MakeMap(B,A), nhận Wrong Answer [14].Trong Bob, phải gọi InitMap đúng một lần, sau đó gọi MakeMap đúng \(M\) lần:
InitMap lần thứ hai: Wrong Answer [15].MakeMap trước InitMap: Wrong Answer [16].Bob kết thúc, chưa gọi InitMap hoặc số lần gọi MakeMap khác \(M\): Wrong Answer [17].Nếu lần gọi Bob bị đánh giá sai, chương trình bị kết thúc ngay.
Alice một lần với các tham số mô tả bản đồ ban đầu.Alice chỉ định, rồi gọi Bob một lần với đồ thị thu được.static để tránh xung đột tên.Header airline.h được cung cấp trong phần tệp đính kèm. Trình chấm thật chạy hai vai trò trong hai tiến trình riêng và khác với trình chấm mẫu một tiến trình của đề gốc.
Trình chấm mẫu đọc dữ liệu từ đầu vào chuẩn theo định dạng sau:
Trình chấm mẫu ghi kết quả ra đầu ra chuẩn theo định dạng sau:
Wrong Answer [1], rồi kết thúc.Alice và Bob đều không bị đánh giá sai, trình chấm mẫu ghi Accepted. và còn xuất giá trị \(V\).Các thông báo không có dấu ngoặc kép. Nếu có nhiều loại lỗi, trình chấm mẫu chỉ thông báo một loại.
Trong nhóm 1 và nhóm 2, chương trình được toàn bộ điểm của nhóm nếu giải đúng tất cả bộ dữ liệu của nhóm.
Trong nhóm 3, nếu chương trình giải đúng tất cả bộ dữ liệu, gọi \(\mathrm{MaxDiff}\) là giá trị lớn nhất của \(V-N\) trên các bộ dữ liệu của nhóm. Điểm được tính như sau:
| Điều kiện | Điểm nhóm 3 |
|---|---|
| \(\mathrm{MaxDiff}\ge 101\) | \(0\) |
| \(21\le\mathrm{MaxDiff}\le 100\) | \(13+\left\lfloor\dfrac{100-\mathrm{MaxDiff}}{4}\right\rfloor\) |
| \(13\le\mathrm{MaxDiff}\le 20\) | \(33+(20-\mathrm{MaxDiff})\times 3\) |
| \(\mathrm{MaxDiff}\le 12\) | \(63\) |
Ở đây, \(\lfloor x\rfloor\) là số nguyên lớn nhất không vượt quá \(x\).
4 3
0 1
0 2
0 3
Các lời gọi diễn ra theo thứ tự sau. Tất cả các hàm trong bảng đều không trả về giá trị.
| Bước | Lời gọi hoặc sự kiện |
|---|---|
| 1 | Trình chấm gọi Alice(...) |
| 2 | Alice gọi InitG(4,3) |
| 3 | Alice gọi MakeG(0,0,1) |
| 4 | Alice gọi MakeG(1,0,2) |
| 5 | Alice gọi MakeG(2,0,3) |
| 6 | Alice kết thúc |
| 7 | Trình chấm gọi Bob(...) |
| 8 | Bob gọi InitMap(4,3) |
| 9 | Bob gọi MakeMap(0,1) |
| 10 | Bob gọi MakeMap(0,2) |
| 11 | Bob gọi MakeMap(0,3) |
| 12 | Bob kết thúc |
Các tham số mà trình chấm truyền vào hai hàm là:
| Tham số | Alice(...) |
Bob(...) |
|---|---|---|
N |
4 |
|
M |
3 |
|
V |
4 |
|
U |
3 |
|
A |
{0,0,0} |
|
B |
{1,2,3} |
|
C |
{2,2,2} |
|
D |
{3,0,1} |
5 7
0 1
0 2
1 3
1 4
3 4
2 3
2 4
JOI 2017/2018 Spring Training Camp, Contest Day 3, đề tiếng Anh chính thức và đề tiếng Nhật chính thức.
Có \(N\) thị trấn của hải ly, được đánh số từ \(1\) đến \(N\) theo thứ tự độ cao giảm dần. Không có hai thị trấn nào có cùng độ cao. Có \(M\) con kênh một chiều nối các cặp thị trấn khác nhau. Con kênh thứ \(i\) chảy từ thị trấn \(S_i\) đến thị trấn \(E_i\). Các con kênh đều chảy từ thị trấn cao xuống thị trấn thấp; không thể di chuyển ngược dòng.
Hải ly Bitaro có \(N\) người bạn, mỗi thị trấn có đúng một người bạn sinh sống. Bitaro dự định tổ chức \(Q\) bữa tiệc và mời bạn bè đến dự. Với bữa tiệc thứ \(j\), có \(Y_j\) người bạn bận nên không thể tham dự. Bữa tiệc này được tổ chức tại thị trấn \(T_j\); những người không thể đi từ thị trấn của mình đến \(T_j\) chỉ bằng các con kênh cũng không thể tham dự. Tất cả những người bạn còn lại đều đến dự tiệc.
Mỗi người đến địa điểm tổ chức tiệc bằng các con kênh. Có thể có nhiều đường đi, nhưng vì các bạn của Bitaro rất thích kênh nên họ luôn chọn một đường đi đi qua nhiều con kênh nhất.
Với mỗi bữa tiệc, hãy tính số con kênh mà người đi qua nhiều kênh nhất trong số những người tham dự đã sử dụng. Nếu không có ai tham dự, hãy trả lời \(-1\).
Đọc từ đầu vào chuẩn:
Các số trên cùng một dòng được phân cách bằng dấu cách.
In \(Q\) dòng ra đầu ra chuẩn. Dòng thứ \(j\) chứa số con kênh lớn nhất mà một người tham dự bữa tiệc thứ \(j\) đi qua. Nếu không có ai tham dự bữa tiệc này, in \(-1\).
Ví dụ 1
5 6 3
1 2
2 4
3 4
1 3
3 5
4 5
4 1 1
5 2 2 3
2 3 1 4 5
1
3
0
Những người tham dự bữa tiệc đầu tiên sống ở các thị trấn \(2,3,4\). Hai người ở thị trấn \(2\) và \(3\) đi qua nhiều kênh nhất để đến thị trấn \(4\): mỗi người đi qua một con kênh. Vì vậy, kết quả là \(1\).
Những người tham dự bữa tiệc thứ hai sống ở các thị trấn \(1,4,5\). Người ở thị trấn \(1\) đi qua nhiều kênh nhất để đến thị trấn \(5\): ba con kênh. Vì vậy, kết quả là \(3\).
Chỉ người sống ở thị trấn \(2\) tham dự bữa tiệc thứ ba. Người này không phải đi qua con kênh nào, nên kết quả là \(0\).
Ví dụ 2
12 17 10
1 2
2 3
3 4
1 5
2 6
3 7
4 8
5 6
6 7
7 8
5 9
6 10
7 11
8 12
9 10
10 11
11 12
6 3 1 7 12
3 7 1 2 3 4 5 6 7
11 3 1 3 5
9 2 1 9
8 4 1 2 3 4
1 1 1
12 0
10 3 1 6 10
11 8 2 3 5 6 7 9 10 11
8 7 2 3 4 5 6 7 8
1
-1
3
1
3
-1
5
2
4
4
JOI 2018, trại huấn luyện mùa xuân, ngày thi 3: Bitaro's Party.
Công ty Just Odd Inventions, gọi tắt là công ty JOI, chuyên tạo ra những phát minh kỳ lạ. Để ngăn thông tin mật bị rò rỉ, công ty lắp một cổng an ninh tại cửa ra vào. Mọi người đều phải đi qua cổng khi vào hoặc ra khỏi công ty, và không thể có từ hai người trở lên đi qua cổng cùng một lúc.
Mỗi khi một người đi qua, cổng ghi lại người đó đang vào hay ra. IOI-kun, một nhân viên của JOI, có bản ghi của cổng trong một ngày, được biểu diễn bằng xâu \(S\). Nếu ký tự thứ \(i\) của \(S\) là (, người thứ \(i\) đi qua cổng đã vào công ty; nếu ký tự đó là ), người ấy đã ra khỏi công ty. IOI-kun biết rằng lúc bắt đầu và kết thúc ngày hôm đó, trong công ty đều không có ai.
Không phải mọi xâu chỉ gồm ( và ) đều có thể là bản ghi hợp lệ. Chẳng hạn, ())( không hợp lệ vì có lúc số người trong công ty sẽ âm; (() không hợp lệ vì cuối ngày vẫn còn người trong công ty.
Ngay sau khi IOI-kun kiểm tra bản ghi, một vi-rút máy tính trong công ty đã sửa đổi xâu \(S\)! Sau khi điều tra, anh cho rằng vi-rút đã thực hiện hai bước sau:
( thành ), còn ) thành (. Gọi xâu thu được là \(S'\). Đoạn được chọn có thể có độ dài \(0\), tức là có thể có \(S'=S\).x. Gọi xâu thu được là \(S''\).IOI-kun không nhớ \(S\) và muốn khôi phục nó từ \(S''\). Trước hết, anh muốn đếm số xâu có thể là \(S'\), không phải \(S\).
Cho \(S''\), hãy tính số xâu khác nhau có thể là \(S'\), lấy phần dư khi chia cho \(1\,000\,000\,007\).
(, ) và x.In một dòng chứa số xâu có thể là \(S'\), lấy phần dư khi chia cho \(1\,000\,000\,007\). Nếu không có xâu nào thỏa mãn, in \(0\).
x trong \(S''\) không quá \(4\).x trong \(S''\) không quá \(12\).x trong \(S''\) không quá \(20\).Ví dụ 1
4
x))x
3
Không thể có \(S'=\) )))(, vì không tồn tại bản ghi hợp lệ \(S\) nào có thể tạo ra xâu này bằng bước đầu tiên.
Có đúng ba khả năng cho \(S'\):
())(, chẳng hạn từ \(S=\) ()().())), chẳng hạn từ \(S=\) ()().)))), chẳng hạn từ \(S=\) (()).Vì vậy, kết quả là \(3\).
Ví dụ 2
10
xx(xx()x(x
45
Ví dụ 3
5
x))x(
0
Ví dụ 4
10
xxxxxxxxxx
684
JOI 2018, trại huấn luyện mùa xuân, ngày thi 3: Security Gate.