Download pdf - Gợi ý PTIT round 6

Transcript
Page 1: Gợi ý PTIT round 6

Một vài gợi ý PTIT round 6

Bài A: Chuyển đổi

Duyệt tất cả các đoạn rồi tính thử số lượng các số 1 có thể được. Tính sẵn số lượng số 1 từ ban

đầu để thực hiện cho việc tính toán nhanh hơn.

Bài B: Tập vẽ

Thực hiện như yêu cầu của đề bài.

Bài C: Người vận chuyển

Mô hình hóa bài toán về đồ thị có hướng.

Chi phí từ đỉnh i đến đỉnh j là d * (khoảng cách manhattan ij) – a[j].

Sau đó sử dụng thuật toán về đường đi ngắn nhất như Dijkstra, Floy để giải quyết.

Bài D: Kiểm tra bài tập

Có nhiều cách để xử lí bài toán này, một trong số đó là sử dụng cây IT, xử lý update 1 phần tử.

Gọi tree[i] là kết quả của dãy số mà nút i đang quản lý. Tree[1] quản lý đoạn 1 … 2^n.

Gọi height là số lần lặp để thu được kết quả của dãy số của nút i.

Nếu height chẵn tree[i] = tree[2*i] ^ tree[2*i + 1];

Nếu height lẻ tree[i] = tree[2*i] | tree[2*i +1];

Khi thay đổi 1 số, ta thấy rằng nó sẽ chỉ ảnh hưởng 1 trong 2 dãy số con của dãy đang xét. Từ đó

xét trường hợp để update theo nút con.

Bài E: Xóa đỉnh.

Bài toán yêu cầu xóa lần lượt các đỉnh, ta sẽ có các đồ thị con mới và ta phải tính đường đi ngắn

nhất của tất cả các cặp đỉnh trong đồ thị này.

Nhìn ngược lại quá trình, thì đó lại là thêm lần lượt các đỉnh và cạnh vào đồ thị đã có trước. Bài

toán sẽ được giải quyết một cách nhìn đơn giản hơn.

Sử dụng Floy để tìm đường đi ngắn nhất giữa tất cả các đỉnh.

Bài F: Dãy số kì diệu

Brute force (trâu bò). Thực hiện kiểm tra cho đến khi các chữ số từ 0->9 xuất hiện đầy đủ trong

dãy số n, 2n, ..., k*n.

Bài G: Vẽ tranh

Bài toán không có gì khó khăn.

Page 2: Gợi ý PTIT round 6

Bài H: Đua thuyền

Quy hoạch động.

Giả sử d là đường kính lớn nhất của chiếc thuyền sao cho nó có thể đi được từ bờ bên trái sang

bờ bên phải.

Thêm các điểm đỏ tại các vị trí có tọa độ bằng với các viên đá (các điểm đỏ như hình vẽ). Xét tất

cả các đường đi từ bờ dưới lên bờ trên (gọi là đường lên), ta thấy hành trình của chiếc thuyền sẽ

cắt tất cả các đường đi này. Với mỗi đường lên này, chiếc thuyền sẽ đi qua đoạn có khoảng cách

lớn nhất.

Vậy gọi cost của mỗi đường lên bằng độ dài cạnh dài nhất trong đường lên đó, ta cần tìm đường

lên có cost nhỏ nhất.

Cách xử lý khác: Chặt nhị phân để tìm giá trị d. Với mỗi giá trị d, tìm xem có thể tìm được

đường lên, đi từ bờ dưới lên bờ trên hay không? Nếu có thì chiếc thuyền có đường kính d không

thể đi qua, nếu không thì d là một giá trị thỏa mãn.

Bài I: Cây khung

Tìm cây khung nhỏ nhất. Thuật toán Prim-set hoặc Krusal.

Với mỗi cặp đỉnh của đồ thị, chỉ cần lưu lại một cạnh có trọng số nhỏ nhất.

Bài J: Nhà trẻ

2 SAT problem

Sử dụng chặt nhị phân để tìm giá trị T nhỏ nhất thõa mãn yêu cầu (có thể sử dụng vòng FOR).

Gọi biến x_i là biến logic cho đứa trẻ thứ i. Mỗi đứa trẻ có 2 sự lựa chọn giáo viên mới, x_i = 1

nếu đứa trẻ học ở lớp giáo viên thứ nhất, x_i = 0 nếu học ở lớp của giáo viên còn lại.

Page 3: Gợi ý PTIT round 6

Với một giá trị T, ta dựng đồ thị chứa các cung đối kháng. Với mỗi nút, vẽ các cung tới các nút

đối kháng (các đứa trẻ nằm ngoài danh sách top T) của nó. Một giá trị T thỏa mãn nếu như tồn

tại một bộ nghiệm (t_1, t_2, ..., t_n) sao cho không vi phạm cung đối kháng nào.

Mỗi cung đối kháng là một biểu thức logic. Xử lí phần còn lại như một bài toán 2-SAT thông

thường.

Bài toán 2-SAT phát biểu như sau:

Cho m biến logic: a1, a2, ... , am và một biểu thức logic C có dạng:

C = (u1|v1) & ... & (un|vn)

Trong đó ui và vi (1 ≤ i ≤ n) được thay bằng biển logic a_j hoặc (!a_j) nào đó (1 ≤ j ≤ m).

Hãy gán giá trị TRUE/FALSE cho các biến a1, a2, ..., a_m sao cho biểu thức C nhận giá trị

TRUE, hoặc thông báo không thể làm được.

Bài toán này có giới hạn n nhỏ, vì vậy cũng thể xử lí bằng cách duyệt thử sai. Lần lượt thử chọn

giá trị cho các x_i, dựa vào đồ thị đã dựng update giá trị cho các nút kề. Nếu không có vi phạm

nào xảy ra, đồ thị đã dựng thỏa mãn và T là một giá trị đúng.

Tham khảo thêm về bài toán 2 SAT: http://www.cs.umd.edu/~gasarch/TOPICS/sat/