Google Code Jam 2017 - Pony Express

Xem PDF




Dạng bài
Ngôn ngữ cho phép
Assembly, Awk, C, C#, C++, Clang, Cobol, D, Groovy, Haskell, JS, Java, Kotlin, Lua, Node JS, OCaml, ObjectiveC, PHP, Pascal, Perl, Prolog, Pypy, Pypy 3, Python, Ruby, Rust, Scala, Scratch, Swift
Điểm: 1700 Thời gian: 1.0s Bộ nhớ: 1G Input: bàn phím Output: màn hình

Năm 1860, Pony Express là hệ thống chuyển thư nhanh nhất nối bờ Đông và bờ Tây Hoa Kỳ. Hệ thống phục vụ \(N\) thành phố. Mỗi thành phố có đúng một con ngựa; mỗi con đi với một tốc độ không đổi nhất định và có tổng quãng đường tối đa mà nó có thể đi trước khi quá mệt để tiếp tục.

Người đưa thư Pony Express khởi hành bằng ngựa của thành phố xuất phát. Mỗi khi tới một thành phố, người đó có thể tiếp tục dùng con ngựa hiện tại hoặc đổi sang ngựa của thành phố ấy; việc đổi ngựa diễn ra tức thời. Ngựa không bao giờ có cơ hội nghỉ, nên một phần sức bền tối đa đã dùng thì mất vĩnh viễn. Khi người đưa thư tới thành phố đích, thư được giao.

Các tuyến giữa thành phố được thiết lập qua những cuộc thương lượng phức tạp giữa chủ công ty, nhà lập pháp, đại diện công đoàn và ông anh họ Pete. Vì vậy khoảng cách không nhất thiết tuân theo lẽ thường: chúng không nhất thiết thỏa bất đẳng thức tam giác, và khoảng cách từ A đến B có thể khác khoảng cách từ B đến A.

Bạn là một doanh nhân du hành thời gian và mang theo một máy tính nhanh từ tương lai. Một máy tính chưa đủ để lập dịch vụ thư điện tử khiến Pony Express lỗi thời, nhưng có thể dùng nó để lập tuyến tối ưu. Với toàn bộ dữ liệu về đường đi, ngựa ở từng thành phố và danh sách các cặp thành phố đầu-cuối, hãy tính nhanh thời gian tối thiểu cho mỗi chuyến giao thư. Mọi chuyến giao thư được xem là độc lập; dùng thành phố hay ngựa trong một chuyến không làm chúng mất đi ở chuyến khác.

Dữ liệu vào

Dòng đầu chứa số lượng bộ test \(T\). Mỗi bộ test gồm:

  • Một dòng chứa \(N\), số thành phố có ngựa, và \(Q\), số cặp điểm dừng cần xét. Các thành phố được đánh số từ 1 đến \(N\).
  • \(N\) dòng, dòng thứ \(i\) chứa \(E_i\), tổng quãng đường tối đa (km) ngựa ở thành phố \(i\) có thể đi, và \(S_i\), tốc độ không đổi (km/h) của nó.
  • \(N\) dòng, mỗi dòng \(N\) số nguyên. Số thứ \(j\) trên dòng thứ \(i\), \(D_{ij}\), bằng -1 nếu không có tuyến trực tiếp từ thành phố \(i\) đến \(j\), và bằng độ dài tuyến đó (km) nếu có.
  • \(Q\) dòng, dòng thứ \(k\) chứa \(U_k,V_k\), lần lượt là điểm xuất phát và điểm đến của cặp thành phố thứ \(k\) cần xét.

Dữ liệu ra

Với mỗi bộ test, in một dòng Case #x: y1 y2 ... yQ, trong đó x là số thứ tự bộ test (bắt đầu từ 1), còn \(y_k\) là thời gian tối thiểu theo giờ để giao thư từ \(U_k\) đến \(V_k\).

Mỗi \(y_k\) được coi là đúng nếu sai số tuyệt đối hoặc tương đối không quá \(10^{-6}\).

Ràng buộc

  • \(1\le T\le100\); \(2\le N\le100\).
  • \(1\le E_i\le10^9\)\(1\le S_i\le1000\) với mọi \(i\).
  • \(-1\le D_{ij}\le10^9\); \(D_{ii}=-1\); \(D_{ij}\ne0\) với mọi \(i,j\).
  • \(U_k\ne V_k\) với mọi \(k\).
  • Mọi chuyến từ \(U_k\) đến \(V_k\) đều được bảo đảm thực hiện được bằng các con ngựa đã cho.
  • Không cặp có thứ tự nào bị lặp trong cùng một bộ test: với mọi \(l\ne m\), \(U_l\ne U_m\) và/hoặc \(V_l\ne V_m\).

Phân nhóm

  • Test Set 1 (Visible): \(D_{ij}=-1\) với mọi \(i,j\)\(i+1\ne j\); các thành phố nằm trên một đường thẳng và mỗi tuyến chỉ đi từ một thành phố tới thành phố kế tiếp. \(Q=1\), \(U_1=1\), \(V_1=N\); chỉ cần tính chuyến từ thành phố đầu đến thành phố cuối.
  • Test Set 2 (Hidden): \(1\le Q\le100\); \(1\le U_k,V_k\le N\) với mọi \(k\).

Điểm các phân nhóm

Mỗi Test Set tương ứng với một subtask trên LQDOJ. Bảng dưới đây giữ nguyên điểm chính thức của Google Code Jam và quy đổi tỷ lệ trên tổng điểm của bài.

Phân nhóm Điểm Google Code Jam Tỷ lệ điểm của bài
Test Set 1 16/40 40%
Test Set 2 24/40 60%

Ví dụ

Ví dụ 1

Input
3
3 1
2 3
2 4
4 4
-1 1 -1
-1 -1 1
-1 -1 -1
1 3
4 1
13 10
1 1000
10 8
5 5
-1 1 -1 -1
-1 -1 1 -1
-1 -1 -1 10
-1 -1 -1 -1
1 4
4 3
30 60
10 1000
12 5
20 1
-1 10 -1 31
10 -1 10 -1
-1 -1 -1 10
15 6 -1 -1
2 4
3 1
3 2
Output
Case #1: 0.583333333
Case #2: 1.2
Case #3: 0.51 8.01 8.0
Note

Bộ test mẫu cuối không thể xuất hiện trong Test Set 1.

Ở bộ #1 có hai lựa chọn: dùng ngựa thành phố 1 cả hành trình hoặc đổi ngựa tại thành phố 2. Cả hai đều đủ sức bền, nhưng ngựa thành phố 2 nhanh hơn, nên đổi ngựa là tốt hơn; tổng thời gian \(1/3+1/4\).

Ở bộ #2 có hai thành phố trung gian. Nếu đổi ngựa ở thành phố 2, con ngựa cực nhanh mới không đủ sức bền nên bắt buộc đổi tiếp ở thành phố 3. Nếu giữ ngựa cũ, tại thành phố 3 có thể đổi hoặc không. Ba phương án lần lượt là: đổi tại cả 2 và 3, mất \(1/10+1/1000+10/8=1.351\); chỉ đổi tại 3, mất \(2/10+10/8=1.45\); không bao giờ đổi, mất \(12/10=1.2\).

Ở bộ #3 có rất nhiều lựa chọn. Với chuyến đầu tiên từ thành phố 2 đến 4, tối ưu là tới thành phố 1 trong \(10/1000\) giờ, đổi ngựa, rồi đi qua 2, 3, 4 bằng ngựa thành phố 1, mất thêm \((10+10+10)/60\) giờ.

Với chuyến thứ hai từ thành phố 3 đến 2, trước hết bắt buộc tới thành phố 4, mất \(10/5\). Con ngựa tương đối nhanh hiện tại không đủ sức đi nơi khác nên phải lấy ngựa thành phố 4. Có thể đi thẳng tới thành phố 1 trong 15 giờ, nhưng chậm hơn đi nó tới thành phố 2 trong 6 giờ rồi dùng ngựa cực nhanh ở thành phố 2 tới thành phố 1 với thêm \(10/1000\) giờ.

Với chuyến thứ ba từ thành phố 3 đến 1, tối ưu là dùng hai bước đầu của chuyến trước, tổng thời gian \(10/5+6=8\).

Nguồn

Google Code Jam 2017, Vòng 1B, bài Pony Express.

Nguồn chính thức trên Google Coding Competitions Archive, phát hành theo giấy phép Apache-2.0.

Bình luận

Mới nhất
Tải bình luận...

Không có bình luận nào.

Kỳ thi: