#include <bits/stdc++.h> using namespace std; typedef pair<int, int> PAIR; int main() { int n, m, i, j; cin >> n >> m; vector<PAIR> v(m); vector<int> flag(n + 1, 0); // 状态标记数组 // 3个case的标志位 bool before = false; bool after = false; bool full = false; for (int k = 0; k < m; ++k) { cin >> i >> j; v[k] = {i, j}; flag[i] = 1; if (flag[i] == 0 && j == 1) flag[i] = 1; // 签到记录 else if (flag[i] == 0 && j == 0) flag[i] = 2; // 只有签退记录 else if (flag[i] == 1 && j == 0) flag[i] = 3; // 签到 + 签退 } // case 1: // 打卡机记录的是一天完整的一段 // 记录里必须是完整的签到签退记录 if (v[0].first == v[m - 1].first && flag[v[0].first] == 3) { full = true; for (int i = 1; i <= n; ++i) { if (flag[i] != 0 && flag[i] != 3) { full = false; break; } } } // case 2: // 打卡机记录的是一天最开始那一段, 且记录里第一个人只有签到没有签退(flag为1) // 记录内存在只签退的(flag为2),说明第一个人不是最开始签到的;若flag为1/3没问题。 // 如: // 1 1 // 2 0 // 这样2势必在1之前签到,1就不可能是第一个签到的, if (v[0].second == 1 && flag[v[0].first] == 1) { before = true; for (int i = 1; i <= n; ++i) { if (i == v[0].first) continue; if (flag[i] == 2) { before = false; break; } } } // case 3: // 打卡机记录的是一天最后那一段,且记录里最后一个人只有签退没有签到(flag是2) // 记录里存在只签到的(flag为1),说明最后一个人不是最后签退的;flag是2/3没问题 // 如: // 1 1 // 2 0 // 这样1势必在2之后签退,2就不可能是最后一个签退的 if (v[m - 1].second == 0 && flag[v[m - 1].first] == 2) { after = true; for (int i = 1; i <= n; ++i) { if (i == v[m - 1].first) continue; if (flag[i] == 1) { after = false; break; } } } for (int i = 1; i <= n; ++i) { if (flag[i] == 0 || ((before || full) && i == v[0].first) || (after && i == v[m - 1].first)) cout << i << " "; } cout << endl; }
全部评论
(3) 回帖