题意:你在看N个小孩在玩石头剪刀布,编号为0 ~ n-1,每个小孩会一直出同一种手势(如果出石头就一直出石头),但是这些小孩中有一个法官,法官想出什么手势就出什么手势。他们总共玩了M局游戏(1~M),a<b表示a输给了b,a>b表示a赢了b,a=b表示平局。问你能否发现这些孩子中的法官,如果发现了是在第几局游戏中发现的?
在解释一下问的内容:
1.”Impossible“谁当法官都不可以使全部对局成立。
2.”Player %d can be determined to be the judge after %d lines“,只有一个法官可以是全部对局成立,编号为%d孩子是法官,你是在第%d局发现的,也就是在第几行你把其他可能的法官,都给推翻了。
3.“Can not determine”表示多个孩子做法官都可以使所有对局成立,你就无法判断哪个孩子是法官了。
思路:枚举每个孩子做法官,初始化并查集,忽略法官在的局。然后看有没有错误,①如果没有,法官数+1,法官编号等于当前的法官
②如果有错误,记录下来第一个错误的地方,跟之前的第一个错误的地方取一个最大值。因为:假设法官只有一个是3号,在前6局的时候,你判断出来2,3,4都可能是法官,你在第7局判断2号不可能是法官,在第9局判断出来4号不可能是法官,那么在第9局你就判断出来了3号是法官。
所以输出”Player 3 can be determined to be the judge after 9 lines。
如果法官数==0,也就是谁当法官都不可以使全部对局成立,输出”Impossible“
如果法官数==1,只有一个法官输出”Player %d can be determined to be the judge after %d lines“,编号为%d孩子是法官,你是在第%d局发现的
如果法官数>=2,有多个人当法官都可以使全部对局成立,则不能判断谁是法官,输出”Can not determine“
//#include<bits/stdc++.h>
#include<cstdio>
#include<iostream>
using namespace std;
const int MAXN = 505;
const int MAXM = 2005;
int n, m, wa, f[MAXN], w[MAXN];//并查集数组和关系数组
//0:相同 1:赢 2:输
struct In
{
int a, b;
char op;
}in[MAXM];//输入
void init()
{
wa = 0;
for (int i = 0; i <= n; i++)
{
f[i] = i; w[i] = 0;
}
}
int Find(int x)
{
if (f[x] == x) return x;
int t = f[x];
f[x] = Find(f[x]);
w[x] = (w[x] + w[t]) % 3;
return f[x];
}
void Union(int a, int b, int D)
{
int root1 = Find(a), root2 = Find(b);
if (root1 != root2)
{
f[root1] = root2;
w[root1] = (w[b] + D - w[a] + 3) % 3;
}
else
{
if ((w[a] - w[b] + 3) % 3 != D) wa++;
}
}
int main()
{
while (~scanf("%d%d", &n, &m))
{
if (m == 0) { printf("Player 0 can be determined to be the judge after 0 lines\n"); continue; }
for (int i = 0; i < m; i++) scanf("%d%c%d", &in[i].a, &in[i].op, &in[i].b);//输入
int cnt = 0, player = 0, line = 0;//可行的法官个数, 法官编号, 行数
for (int i = 0; i < n; i++)//枚举每个人做法官
{
init();//初始化
for (int j = 0; j < m; j++)//
{
if (in[j].a == i || in[j].b == i) continue;//有法官的局跳过
if (in[j].op == '=') Union(in[j].a, in[j].b, 0);//a,b平局
else if (in[j].op == '>') Union(in[j].a, in[j].b, 1);//a赢b
else if (in[j].op == '<') Union(in[j].a, in[j].b, 2);//a输b
if (wa == 1) { line = max(line, j + 1); break; }//错误的地方
}
if (wa == 0) { cnt++; player = i; }
}
if (cnt == 0) printf("Impossible\n");//谁当都不行
else if(cnt == 1) printf("Player %d can be determined to be the judge after %d lines\n", player, line);//只有一个裁判
else if(cnt >= 2) printf("Can not determine\n");//找不到(即有多个人当裁判都可以)
}
return 0;
}
/*
3 3
0<1
1<2
2<0
3 5
0<1
0>1
1<2
1>2
0<2
4 4
0<1
0>1
2<3
2>3
1 0
*/
/*
Can not determine
Player 1 can be determined to be the judge after 4 lines
Impossible
Player 0 can be determined to be the judge after 0 lines
*/