// yukicoder: No.580 旅館の予約計画 // bal4u 2019.8.19 #include #include #include //// 入出力関係 #if 1 #define gc() getchar_unlocked() #else #define gc() getchar() #endif int in() { // 非負整数の入力 int n = 0, c = gc(); do n = 10 * n + (c & 0xf); while (isdigit(c = gc())); return n; } //// 優先度付きキュー #define MAX 2000 typedef struct { int a, n; } QUE; QUE qmi[MAX]; int qsmi; QUE qma[MAX]; int qsma; #define PARENT(i) ((i)>>1) #define LEFT(i) ((i)<<1) #define RIGHT(i) (((i)<<1)+1) void min_heapify(int i) { int l, r, mi; l = LEFT(i), r = RIGHT(i); if (l < qsmi && qmi[l].a < qmi[i].a) mi = l; else mi = i; if (r < qsmi && qmi[r].a < qmi[mi].a) mi = r; if (mi != i) { QUE qt = qmi[i]; qmi[i] = qmi[mi]; qmi[mi] = qt; min_heapify(mi); } } void dmi() { qmi[0] = qmi[--qsmi]; min_heapify(0); } void emi(int a, int n) { int i, mi; i = qsmi++; qmi[i].a = a, qmi[i].n = n; while (i > 0 && qmi[i].a < qmi[mi = PARENT(i)].a) { QUE qt = qmi[i]; qmi[i] = qmi[mi]; qmi[mi] = qt; i = mi; } } void max_heapify(int i) { int l, r, ma; l = LEFT(i), r = RIGHT(i); if (l < qsma && qma[l].a > qma[i].a) ma = l; else ma = i; if (r < qsma && qma[r].a > qma[ma].a) ma = r; if (ma != i) { QUE qt = qma[i]; qma[i] = qma[ma]; qma[ma] = qt; max_heapify(ma); } } void dma() { qma[0] = qma[--qsma]; max_heapify(0); } void ema(int a, int n) { int i, ma; i = qsma++; qma[i].a = a, qma[i].n = n; while (i > 0 && qma[i].a > qma[ma = PARENT(i)].a) { QUE qt = qma[i]; qma[i] = qma[ma]; qma[ma] = qt; i = ma; } } //// 本問題関連 typedef struct { int tm1, tm2; int n; } T; // チェックイン、アウト時刻、id T tbl[1005]; int m; // 予約情報、予約数 int n; // 部屋数 char ng[1005]; // 予約不能 int cmp(const void *u, const void *v) { return ((T *)u)->tm1 - ((T *)v)->tm1; } // for qsort() int main() { int i, ans; n = in(), m = in(); for (i = 1; i <= m; i++) { tbl[i].tm1 = (in()*24 + in())*60 + in(); tbl[i].tm2 = (in()*24 + in())*60 + in() + 1; tbl[i].n = i; } qsort(tbl+1, m, sizeof(T), cmp); ans = 0; for (i = 0; i < n; i++) emi(-200+i, 0), ema(-200+i, 0); for (i = 1; i <= m; i++) { // チェックアウト時刻をふたつの優先度付きキューで管理 while (ng[qmi[0].n]) dmi(); // キャンセルにした予約情報を取り除く if (qmi[0].a <= tbl[i].tm1) { // チェックアウト時刻が最も早い予約に対し、 dmi(), ans++, emi(tbl[i].tm2, tbl[i].n), ema(tbl[i].tm2, tbl[i].n); } else { // 予約不能につき、チェックアウト時刻の最も遅い予約と入れ替える作業 while (ng[qma[0].n]) dma(); // キャンセルにした予約情報を取り除く if (tbl[i].tm2 < qma[0].a) { ng[qma[0].n] = 1, dma(); // キャンセルした! emi(tbl[i].tm2, tbl[i].n), ema(tbl[i].tm2, tbl[i].n); // 入れ替える } } } printf("%d\n", ans); return 0; }