枚举+关系并查集,并查集与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 ;
}