枚举+关系并查集,并查集与1182相似,枚举每个小孩为judge时的情况,若当前枚举情况下每个round都是正确的,则当前枚举编号可能是judge。若只找到一个judge的可能,则找出排除其他编号所需最多的round数,两者即为输出。
做了一整天,WA了9次,原因是偏移量r公式搞错一个地方,列了好多次表才搞定。
code:
#include<cstdio>
#include<cstring>
using namespace std ;
int f[501] ;
int r[501] ;
int x[2001] ;
int y[2001] ;
int ans[501] ;
void make_set(int n){
for(int i=0; i<n; i++){
f[i] = i ;
r[i] = 0 ;
}
}
int find_set(int x){
int temp ;
if(x==f[x])
return x ;
temp = f[x] ;
f[x] = find_set(temp) ;
r[x] = (r[temp]+r[x]) % 3 ;
return f[x] ;
}
void union_set(int x, int y, int fx, int fy, int d){
f[fy] = fx ;
r[fy] = (3+d+r[x]-r[y]+r[fx]) % 3 ;
}
int main(){
int n, m, i, j, fx, fy, p, s, count ;
int d[2001] ;
while(~scanf("%d%d", &n, &m)){
memset(ans, 0, sizeof(ans)) ;
for(i=0; i<m; i++){
scanf("%d", &x[i]) ;
char c = getchar() ;
scanf("%d", &y[i]) ;
if(c=='=') d[i] = 0 ;
else if(c=='<') d[i] = 1 ;
else d[i] = 2 ;
}
for(i=0; i<n; i++){
make_set(n) ;
for(j=0; j<m; j++){
if(x[j]==i||y[j]==i) continue ;
fx = find_set(x[j]) ;
fy = find_set(y[j]) ;
if(fx!=fy)
union_set(x[j], y[j], fx, fy, d[j]) ;
else
if((r[x[j]]+d[j])%3!=r[y[j]]){
ans[i] = j + 1 ; //记录出错位置
break ;
}
}
}
s = 0, count = 0 ;
for(i=0; i<n; i++){
if(ans[i]==0){
count ++ ;
p = i ;
}
if(ans[i]>s)
s = ans[i] ;
}
if(count==0) printf("Impossible\n") ;
else if(count>1) printf("Can not determine\n") ;
else printf("Player %d can be determined to be the judge after %d lines\n", p, s) ;
}
return 0 ;
#include<cstring>
using namespace std ;
int f[501] ;
int r[501] ;
int x[2001] ;
int y[2001] ;
int ans[501] ;
void make_set(int n){
for(int i=0; i<n; i++){
f[i] = i ;
r[i] = 0 ;
}
}
int find_set(int x){
int temp ;
if(x==f[x])
return x ;
temp = f[x] ;
f[x] = find_set(temp) ;
r[x] = (r[temp]+r[x]) % 3 ;
return f[x] ;
}
void union_set(int x, int y, int fx, int fy, int d){
f[fy] = fx ;
r[fy] = (3+d+r[x]-r[y]+r[fx]) % 3 ;
}
int main(){
int n, m, i, j, fx, fy, p, s, count ;
int d[2001] ;
while(~scanf("%d%d", &n, &m)){
memset(ans, 0, sizeof(ans)) ;
for(i=0; i<m; i++){
scanf("%d", &x[i]) ;
char c = getchar() ;
scanf("%d", &y[i]) ;
if(c=='=') d[i] = 0 ;
else if(c=='<') d[i] = 1 ;
else d[i] = 2 ;
}
for(i=0; i<n; i++){
make_set(n) ;
for(j=0; j<m; j++){
if(x[j]==i||y[j]==i) continue ;
fx = find_set(x[j]) ;
fy = find_set(y[j]) ;
if(fx!=fy)
union_set(x[j], y[j], fx, fy, d[j]) ;
else
if((r[x[j]]+d[j])%3!=r[y[j]]){
ans[i] = j + 1 ; //记录出错位置
break ;
}
}
}
s = 0, count = 0 ;
for(i=0; i<n; i++){
if(ans[i]==0){
count ++ ;
p = i ;
}
if(ans[i]>s)
s = ans[i] ;
}
if(count==0) printf("Impossible\n") ;
else if(count>1) printf("Can not determine\n") ;
else printf("Player %d can be determined to be the judge after %d lines\n", p, s) ;
}
return 0 ;
}