360笔试第一题打卡

#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;
}

#笔试题型##360公司#
全部评论
靠印象整理,可能略有偏差
点赞 回复 分享
发布于 2020-09-11 22:53
厉害
点赞 回复 分享
发布于 2020-09-11 22:53
通过率100%吗?
点赞 回复 分享
发布于 2020-09-12 10:12

相关推荐

点赞 评论 收藏
分享
1 1 评论
分享
牛客网
牛客企业服务