Lý lịch
Tôi đã được truyền cảm hứng từ video gần đây của 3Blue1Brown về vấn đề tách vòng cổ (hay như ông gọi nó là vấn đề vòng cổ bị đánh cắp) và mối quan hệ của nó với định lý Borsuk-Ulam .
Trong vấn đề này, hai tên trộm đã đánh cắp một chiếc vòng cổ có giá trị bao gồm nhiều loại trang sức khác nhau. Có một số lượng chẵn của từng loại trang sức và những tên trộm muốn chia đều từng loại trang sức giữa hai loại. Điều hấp dẫn là họ phải làm như vậy bằng cách chia vòng cổ thành một số phân đoạn liền kề và phân phối các phân đoạn giữa hai người họ.
Dưới đây là một ví dụ với bốn loại ngọc ký hiệu S
, E
, D
, và R
(cho sapphire, ngọc lục bảo, kim cương, ruby và, tương ứng). Hãy nói rằng vòng cổ như sau:
[S,S,S,E,S,D,E,R,S,R,E,S,S,S,D,R,E,E,R,E,D,E,R,R,D,E,E,E]
Có 8
ngọc bích, 10
ngọc lục bảo, 4
kim cương và 6
hồng ngọc. Chúng ta có thể chia vòng cổ như sau:
[[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
Sau đó, nếu chúng ta đưa các phân đoạn thứ nhất, thứ ba và thứ năm cho một tên trộm và các phân đoạn thứ hai và thứ tư cho kẻ trộm khác, mỗi phân đoạn sẽ kết thúc bằng 4
ngọc bích, 5
ngọc lục bảo, 2
kim cương và 3
hồng ngọc:
[S], [S,E,S,D,E,R,S], [R,R,D,E,E,E]
[S], [R,E,S,S,S,D,R,E,E,R,E,D,E],
Sử dụng 0
-indexing, những vết cắt này xảy ra tại các chỉ số [1,2,9,22]
.
Mục tiêu
Nó chỉ ra rằng một phân chia công bằng như vậy luôn có thể được thực hiện bằng cách sử dụng tại hầu hết các n
vết cắt, trong đó n
số lượng các loại trang sức. Nhiệm vụ của bạn là viết một chương trình hoặc chức năng hoàn chỉnh, lấy một vòng cổ làm đầu vào và đưa ra một phép chia tối thiểu như vậy (số lần cắt ít nhất).
Đầu vào
Đầu vào có thể ở bất kỳ định dạng thuận tiện. Vòng cổ nên là một chuỗi trang sức và không có gì hơn; ví dụ: danh sách các số nguyên, từ điển với các khóa đại diện cho các loại trang sức và giá trị là danh sách các chỉ số. Bạn có thể tùy ý bao gồm chiều dài của vòng cổ hoặc số loại trang sức riêng biệt, nhưng bạn không nên lấy bất kỳ đầu vào nào khác.
Bạn có thể cho rằng vòng cổ đầu vào là hợp lệ. Bạn không cần phải xử lý trường hợp có một số lượng trang sức lẻ của một loại nhất định hoặc vòng cổ trống.
Đầu ra
Một lần nữa, đầu ra có thể ở bất kỳ định dạng thuận tiện; ví dụ: danh sách các phân đoạn, danh sách các vị trí cắt, từ điển với các khóa đại diện cho hai tên trộm và giá trị là danh sách các phân đoạn, v.v. Các phân đoạn có thể được biểu thị bằng chỉ mục bắt đầu, chỉ mục kết thúc, danh sách các chỉ số liên tiếp, danh sách trang sức, độ dài của chúng, v.v. Bạn có thể sử dụng 0
- hoặc 1
- lập chỉ mục. Nếu thứ tự không quan trọng đối với định dạng của bạn, thì đầu ra của bạn có thể theo bất kỳ thứ tự nào. Đây là đầu ra ở trên trong một số định dạng khác nhau:
list of segments: [[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
list of cuts: [1,2,9,22]
list of lengths: [1,1,7,13,6]
dictionary: {'thief1' : [(R,R,D,E,E,E),(S),(S,E,S,D,E,R,S)], 'thief2' : [(S),(R,E,S,S,S,D,R,E,E,R,E,D,E)]}
Lưu ý rằng thứ tự rất quan trọng trong danh sách các phân đoạn (phân đoạn xen kẽ giữa những tên trộm) và danh sách độ dài (để xác định các phân đoạn), nhưng không có trong danh sách cắt giảm hoặc từ điển. Chỉnh sửa: Greg Martin chỉ ra rằng đây sẽ không phải là kết quả đầu ra hợp lệ vì có thể thu được sự phân chia công bằng trong hai lần cắt
Các trường hợp thử nghiệm
[1,2,1,2,1,3,1,3,3,2,2,3] -> [[1,2,1],[2,1,3,1],[3,3,2],[2,3]]
[1,1,1,1,2,2,3,3,3,3,3,3] -> [[1,1],[1,1,2],[2,3,3,3],[3,3,3]]
[1,1,1,1,1,1,1,1,1,1,1,1] -> [[1,1,1,1,1,1],[1,1,1,1,1,1]]
[1,1,1,1,2,3,4,2,3,4,2,2] -> [[1,1],[1,1,2,3,4,2],[3,4,2,2]]
Ghi chú
- Sơ hở tiêu chuẩn bị cấm.
- Đây là môn đánh gôn ; câu trả lời ngắn nhất (tính bằng byte) thắng.
[S,S,S,E,S,D,E,R,S,R,E,S,S,S,D,R,E,E,R,E,D,E,R,R,D,E,E,E]
, có vẻ như đầu ra phải như vậy [[S,S,S,E,S,D,E,R],[S,R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
, vì nó có ít vết cắt hơn [[S],[S],[S,E,S,D,E,R,S],[R,E,S,S,S,D,R,E,E,R,E,D,E],[R,R,D,E,E,E]]
. Tôi có hiểu đúng thông số kỹ thuật không?