Thuật toán: Gọi là số lần An sử dụng cửa để đi từ phòng đến phòng.. Độ phức tạp thuật toán.. Thuật toán: Gọi: • bằng hoặc hoặc tương ứng ô trống hoặc ô chứa quân màu đỏ của Alice hoặc ch
Trang 10 1 2
ĐÁP ÁN VÀ BIỀU ĐIỂM Bài 1 Đường đi dài (7 điểm)
Phân bổ điểm:
• Subtask 1 (25%): ;
• Subtask 2 (25%): ;
• Subtask 3 (25%): ;
• Subtask 4 (25%): Không có thêm ràng buộc nào
Thuật toán:
Gọi là số lần An sử dụng cửa để đi từ phòng đến phòng
Đường đi từ phòng tới phòng có dạng:
Do đó ta có công thức tính như sau:
• ;
• Với :
Câu trả lời của bài toán là
Độ phức tạp thuật toán
Bài 2 Trò chơi trên bảng (7 điểm)
Phân bổ điểm:
• Subtask 1 (50%): ;
• Subtask 2 (50%): Không có thêm ràng buộc nào
Thuật toán:
Gọi:
• bằng hoặc hoặc tương ứng ô trống hoặc ô chứa quân màu đỏ (của Alice) hoặc chứa quân màu xanh (của Bob) Ban đầu tất cả các đều bằng ;
• là số quân hiện có của cột Như vậy khi thả một quân vào cột , ta có sẽ tăng lên và hàng hiện thời của quân này sẽ là (hàng được đánh số từ đến theo thứ tự từ dưới lên trên);
• là số quân cùng màu với quân ở ô và được tính từ ô này đi theo hướng Ta đánh số các hướng như sau:
Bây giờ khi quân thứ thả xuống ở cột , ta cần cập nhật thông tin cho các biến và kiểm tra xem ở bước này có người chiến thắng hay không như sau:
for (int i = 1; i <= h * w ; i ++) {
int c ; // cột đặt quân
cin >> c
int r = ++ col [ ]; // hàng đặt quân
a [ ][ c ] = i % 2; // a[r][c] ghi lai quân của Alice hay Bob
1
Trang 2for (int dir = 0; dir < 4; dir ++) {
// tính số ô theo hướng dir
int len1 = ( a r ][ c ] == a r + DI [ dir ]][ c + DJ [ dir ]] ? d r + DI [ dir ]][ c +
DJ [ dir ]][ dir ] : 0);
// tính số ô theo hướng ngược lại 7 - dir
int len2 = ( a r ][ c ] == a r - DI [ dir ]][ c - DJ [ dir ]] ? d r - DI [ dir ]][ c -
DJ [ dir ]][7 - dir ] : 0);
// độ dài theo hai hướng dir & 7 - dir
int len = len1 + 1 + len2 ;
if ( len >= k ) {
cout << char('A' + ( i - 1) % 2) << ' ' << i << '\n';
return 0
}
// chỉ cần cập nhật tại ô cuối của hướng dir
d [ r + len1 * DI [ dir ]][ c + len1 * DJ [ dir ]][7 - dir ] = len ;
d [ r + len2 * DI [7 - dir ]][ c + len2 * DJ [7 - dir ]][ dir ] = len ;
}
}
cout << "D\n" ;
Độ phức tạp thuật toán là
Bài 3 Màu sắc trên cây (6 điểm)
Phân bổ điểm:
• Subtask 1 (20%): ;
• Subtask 2 (23%): Chỉ có truy vấn loại thứ ;
• Subtask 3 (20%): Chỉ có truy vấn loại ;
• Subtask 4 (20%): Chỉ có truy vấn loại ;
• Subtask 5 (17%): Không có thêm ràng buộc nào
Thuật toán:
Trong bài toán này ta cần xử lý các truy vấn trên đường đi giữa hai nút của cây, vì vậy ta sử dụng kỹ thuật Heavy-light decomposition để phân rã cây
Ngoài ra ta cũng phải xử lý tất cả các nút trong cây con của một nút Nhận thấy rằng sau khi phân rã cây, các nút của một cây con được phân rã vào các vị trí liên tiếp và điều này rất thuận lợi cho việc xử
lý truy vấn Vì vậy trong quá trình phân ra cây, ngoài việc tính cho biết vị trí của nút trong mảng phân
rã, ta còn tính thêm là vị trí cuối cùng của nút trong cây con gốc trong mảng phân rã Vì vậy việc xử
lý truy vấn đối với cây con gốc sẽ tương ứng với các vị trí từ đến trong mảng phân rã
Sau khi phân rã cây xong, việc xử lý các truy vấn sẽ trên mảng phân rã bằng cấu trúc dữ liệu Segment Tree với cập nhật lười Mỗi nút của Segment Tree ta sẽ lưu các thông tin: màu của phần tử bên trái, phải của đoạn và số lần thay đổi màu khi đi từ trái sang phải của đoạn đó
Độ phức tạp thuật toán là
Hết
-2