[AcWing 258] 石头剪刀布
带扩展域的并查集
点击查看代码
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6 + 10;
int n, m;
int p[N];
struct Node
{
int a, b;
char op;
} s[N];
int find(int x)
{
if (p[x] != x)
p[x] = find(p[x]);
return p[x];
}
void merge(int a, int b)
{
int pa = find(a), pb = find(b);
p[pa] = pb;
}
bool same(int a, int b)
{
return find(a) == find(b);
}
bool check(int a, int b, char c)
{
if (c == '=') {
if (same(a, b + n) || same(a + n, b))
return false;
merge(a, b);
merge(a + n, b + n);
merge(a + n + n, b + n + n);
}
else if (c == '>') {
if (same(a, b) || same(a + n, b))
return false;
merge(a, b + n);
merge(a + n, b + n + n);
merge(a + n + n, b);
}
else {
if (same(a, b) || same(a, b + n))
return false;
merge(a + n, b);
merge(a + n + n, b + n);
merge(a, b + n + n);
}
return true;
}
void solve()
{
while (cin >> n >> m) {
for (int i = 1; i <= m; i ++) {
int a, b;
char op;
cin >> a >> op >> b;
s[i] = {a, b, op};
}
// 记录裁判的个数
int cnt = 0;
// 记录裁判的编号
int res = 0;
// 记录得到裁判信息的行号
int the_line = 0;
// 假设编号为 t 的人是裁判
for (int t = 0; t < n; t ++) {
// 每次都要将集合初始化
for (int i = 0; i < 3 * n; i ++)
p[i] = i;
bool is_ok = true;
for (int i = 1; i <= m; i ++) {
auto& [a, b, op] = s[i];
// 将裁判跳过
if (a == t || b == t)
continue;
// 检查是否合法,合法则合并集合,不会进入if中
if (!check(a, b, op)) {
// 不合法才会进入
is_ok = false;
// 其他人不是裁判的最大轮数
if (the_line <= i)
the_line = i;
break;
}
}
if (is_ok) {
res = t;
cnt ++;
}
}
if (!cnt)
printf("Impossible\n");
else if (cnt > 1)
printf("Can not determine\n");
else
printf("Player %d can be determined to be the judge after %d lines\n", res, the_line);
}
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
solve();
return 0;
}
- 判断裁判的思路
先假设一定存在裁判,枚举把每个人当作裁判,然后将包含他的数据跳过,判断其他数据是否会推出矛盾,如果没有矛盾,则说明这个人可能是裁判,就把 ,考虑以下几种情况:
① 如果只有一位裁判,那么只有当枚举到把他当作裁判时,其他数据才会没有矛盾, 只会执行一次,最终
② 如果有裁判,但是不能确定哪个是裁判,那么有多个人选,把他当作裁判时,其他数据没有矛盾, 会执行超过一次,
③ 其他情况是上述两种情况的补集,也就是必须没有裁判或者必须有多个裁判, 只能取 (没有裁判这种情况首先就不符合前提假设 “先假设一定存在裁判”, 只能说明是 “必须没有裁判或者必须有多个裁判” 两种情况的一种,不能具体到是哪一种情况) - 扩展域
对于 号小朋友, 代表该小朋友出的是石头, 代表该小朋友出的是剪刀, 代表该小朋友出的是布 - 最早的找到裁判的时间 判断出除他以外的人都不是裁判的时间 判断出其他人不是裁判的时间的最大值
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!