Bài 20.4. Quản Lý Lịch Trình Đặt Lịch Hẹn - [Độ khó: Khó]
Bài 20.4. Quản Lý Lịch Trình Đặt Lịch Hẹn - [Độ khó: Khó]
Bạn đang phát triển một hệ thống quản lý lịch hẹn cho một phòng khám. Hệ thống cần lưu trữ các cuộc hẹn theo từng ngày. Mỗi cuộc hẹn có một mã ID duy nhất, tên bệnh nhân, thời gian bắt đầu và thời gian kết thúc (được biểu diễn bằng số nguyên từ 0 đến 1440, đại diện cho phút trong ngày, ví dụ: 0 là 00:00, 60 là 01:00, 720 là 12:00). Hệ thống cần cho phép:
- Đặt lịch hẹn mới cho một ngày cụ thể.
- Hủy một cuộc hẹn đã có.
- Hiển thị tất cả các cuộc hẹn của một ngày theo thứ tự thời gian.
- Quan trọng nhất: Sau mỗi thao tác thêm/hủy lịch hẹn trên một ngày, hệ thống cần kiểm tra và cảnh báo nếu có cuộc hẹn nào bị trùng lặp về thời gian (overlapping) trong ngày đó. Hai cuộc hẹn
[start1, end1]
và[start2, end2]
trùng lặp nếumax(start1, start2) < min(end1, end2)
.
Mô tả: Bài tập này đòi hỏi việc quản lý dữ liệu phức tạp hơn trong std::map
. Giá trị của map
không chỉ là một kiểu đơn giản mà là một tập hợp các cuộc hẹn (có thể là std::vector
hoặc std::list
các struct/class Appointment
). Việc duy trì thứ tự thời gian cho các cuộc hẹn trong mỗi ngày và kiểm tra trùng lặp sau mỗi thay đổi là thử thách chính, yêu cầu tư duy về cấu trúc dữ liệu lồng nhau và thuật toán kiểm tra chồng chéo.
INPUT FORMAT
Dòng đầu tiên chứa số nguyên Q
(1 <= Q
<= 1000), là tổng số truy vấn.
Q
dòng tiếp theo, mỗi dòng là một truy vấn theo định dạng sau:
ADD [Ngày] [ID] [Tên bệnh nhân] [Thời gian bắt đầu] [Thời gian kết thúc]
: Thêm một cuộc hẹn.Ngày
có dạngYYYY-MM-DD
.ID
là số nguyên duy nhất.Tên bệnh nhân
là chuỗi không khoảng trắng.Thời gian bắt đầu/kết thúc
là số nguyên từ 0 đến 1440 (phút).Thời gian bắt đầu
luôn nhỏ hơnThời gian kết thúc
.CANCEL [Ngày] [ID]
: Hủy cuộc hẹn cóID
vàoNgày
đó. Nếu không tìm thấy, bỏ qua.LIST [Ngày]
: Liệt kê tất cả các cuộc hẹn củaNgày
đó theo thứ tự thời gian bắt đầu tăng dần.CHECK [Ngày]
: Kiểm tra và in raOVERLAP
nếu có bất kỳ cặp cuộc hẹn nào trùng lặp về thời gian trong ngày đó. Ngược lại, in raNO OVERLAP
.
OUTPUT FORMAT
Kết quả của mỗi truy vấn sẽ được in ra theo yêu cầu.
ADD
,CANCEL
: Không in ra gì, nhưng sauADD
vàCANCEL
(nếu thành công), hệ thống ngầm phải kiểm tra và cập nhật trạng thái trùng lặp cho ngày đó.LIST [Ngày]
: In mỗi cuộc hẹn trên một dòng theo định dạng[Thời gian bắt đầu]-[Thời gian kết thúc] [Tên bệnh nhân] (ID: [ID])
. Nếu không có cuộc hẹn nào, inNO APPOINTMENTS
.CHECK [Ngày]
: InOVERLAP
hoặcNO OVERLAP
.
Ví dụ:
Input:
8
ADD 2023-10-26 101 Alex 900 960
ADD 2023-10-26 102 Bella 950 1000
LIST 2023-10-26
CHECK 2023-10-26
ADD 2023-10-26 103 Charlie 1000 1050
CHECK 2023-10-26
CANCEL 2023-10-26 102
CHECK 2023-10-26
Output:
900-960 Alex (ID: 101)
950-1000 Bella (ID: 102)
OVERLAP
OVERLAP
NO OVERLAP
Giải thích:
- ADD 101 Alex 900-960: Hẹn Alex từ 15:00 đến 16:00.
- ADD 102 Bella 950-1000: Hẹn Bella từ 15:50 đến 16:40.
- LIST 2023-10-26: In ra cả hai cuộc hẹn.
- CHECK 2023-10-26: (Alex 900-960) và (Bella 950-1000) trùng lặp vì
max(900, 950) = 950
vàmin(960, 1000) = 960
, mà950 < 960
. InOVERLAP
. - ADD 103 Charlie 1000-1050: Hẹn Charlie từ 16:40 đến 17:30.
- CHECK 2023-10-26: Vẫn có cặp trùng lặp (Alex, Bella). In
OVERLAP
. - CANCEL 2023-10-26 102: Hủy hẹn Bella.
- CHECK 2023-10-26: Sau khi hủy Bella, chỉ còn Alex (900-960) và Charlie (1000-1050). Hai cuộc hẹn này không trùng lặp (
max(960, 1000) = 1000
,min(960, 1050) = 960
, nhưng1000
không nhỏ hơn960
là sai logic,max(960, 1000)
= 1000,min(960, 1050)
= 960,max(960, 1000) < min(960, 1050)
là1000 < 960
-> False. Do đó, không trùng lặp). InNO OVERLAP
. - Lưu ý: Để kiểm tra chồng chéo hiệu quả trong một danh sách, bạn nên sắp xếp các cuộc hẹn theo thời gian bắt đầu và sau đó duyệt qua chúng, so sánh
endTime
của cuộc hẹn hiện tại vớistartTime
của cuộc hẹn tiếp theo.
Comments