Bài 20.4. Quản Lý Lịch Trình Đặt Lịch Hẹn - [Độ khó: Khó]


LÀM BÀI

Points: 10 (partial)
Time limit: 2.0s
Memory limit: 64M

Author:
Problem type

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:

  1. Đặt lịch hẹn mới cho một ngày cụ thể.
  2. Hủy một cuộc hẹn đã có.
  3. Hiển thị tất cả các cuộc hẹn của một ngày theo thứ tự thời gian.
  4. 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][start2, end2] trùng lặp nếu max(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ạng YYYY-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ơn Thời gian kết thúc.
  • CANCEL [Ngày] [ID]: Hủy cuộc hẹn có ID vào Ngà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ủa Ngày đó theo thứ tự thời gian bắt đầu tăng dần.
  • CHECK [Ngày]: Kiểm tra và in ra OVERLAP 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 ra NO 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 sau ADDCANCEL (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, in NO APPOINTMENTS.
  • CHECK [Ngày]: In OVERLAP hoặc NO 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) = 950min(960, 1000) = 960, mà 950 < 960. In OVERLAP.
  • 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ưng 1000 không nhỏ hơn 960 là sai logic, max(960, 1000) = 1000, min(960, 1050) = 960, max(960, 1000) < min(960, 1050)1000 < 960 -> False. Do đó, không trùng lặp). In NO 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ới startTime của cuộc hẹn tiếp theo.

Comments

There are no comments at the moment.

Zalo