Rochambeau POJ - 2912

原题链接

考察:并查集+枚举

错误思路:

       接收了所有的判断语句,当出现矛盾的时候玩游戏的两人犯规次数+1,输出犯规最多的人.

       很明显错在有裁判的关系是不准确的,因为那段关系不能考虑

正确思路:

       枚举每个可能为裁判的人,如果可能为裁判的人>1,则不能确定;如果=1,则输出此人.如果==0,则impossible

       说实话,这种思路感觉有点矛盾.这样就不能判断必须为裁判的人数,而题目要求必须为裁判的人>1则输出impossible,但是此解输出不能确定.

       但是看了网上基本是这种思路,或者这个思路换成不能为裁判的人数.

       这题真诡异,可能是我没理解题意

易错:

       每次枚举一人都要重新建树

       裁判需要每个人都和他出现矛盾才能判定,没有裁判乱出子是不会出现矛盾的,我们确定矛盾是最晚出现矛盾的那句.

 1 #include <iostream>
 2 using namespace std;//想清楚再写题啊!!!! 
 3 const int N = 520;
 4 int p[N],d[N],pos[N];
 5 struct game{
 6     int l,r;
 7     char ans;
 8 }query[2010];
 9 int findf(int x)
10 {
11     if(p[x]!=x){
12         int t = findf(p[x]);
13         d[x]+=d[p[x]];
14         p[x] = t;
15     }
16     return p[x];
17 }
18 int main()
19 {
20     freopen("in.txt","r",stdin);
21     int n,m;
22     while(~scanf("%d%d",&n,&m))
23     {
24         if(n==1) { printf("Player 0 can be determined to be the judge after 0 lines\n"); continue;}
25         fill(pos,pos+N,0);
26         int cnt = 0; int ans = 0; int id = 0;
27         //我们需要枚举裁判,因为有裁判的 关系是不准确的
28         for(int i=1;i<=m;i++)  scanf("%d %c %d",&query[i].l,&query[i].ans,&query[i].r);//输入处理很妙,空格既会被跳过,多余空格还会被接受 
29         for(int i=0;i<n;i++){
30             for(int k=0;k<n;k++) p[k] = k;
31             fill(d,d+N,0); 
32             for(int j=1;j<=m;j++){
33                 int x = query[j].l; int y = query[j].r;
34                 if(x==i||y==i) continue;
35                 int px = findf(x); int py = findf(y);
36                 if(query[j].ans=='>'){
37                     if(px!=py){
38                        d[px] = 1+d[y]-d[x];
39                        p[px] = py;
40                     }else{
41                        if((d[x]-d[y]-1)%3==0) continue;
42                        else{
43                              pos[i]=j; break;
44                        }
45                     }
46                 }else if(query[j].ans=='<'){
47                     if(px!=py){
48                         d[px] = d[y]-d[x]+2;
49                         p[px] = py;
50                     }else{
51                         if((d[x]-d[y]+ 1)%3==0) continue;
52                         else{
53                             pos[i]=j; break;
54                         }
55                     }
56                 }else{
57                     if(px!=py){
58                         d[px] = d[y]-d[x];
59                         p[px] = py;
60                     }else{
61                         if((d[x]-d[y])%3==0) continue;
62                         else{
63                             pos[i]=j; break;
64                         }
65                     }
66                 }                      
67             }
68         }
69         for(int i=0;i<n;i++){
70             if(!pos[i]) { cnt++; id=i;}//pos[i]==0表示它没有出现矛盾 
71             else ans = max(ans,pos[i]);//出现矛盾,说明矛盾处存在裁判,但是本题我们需要看所有的人出现后判断 
72         } 
73         if(cnt>1) printf("Can not determine\n");
74         else if(!cnt) printf("Impossible\n");
75         else if(cnt==1) printf("Player %d can be determined to be the judge after %d lines\n",id,ans);
76     }
77     return 0;
78 }

 

通过此题也回忆了一个很妙的输入处理方式:利用scanf的空格既允许输入空格,也可以不让空格影响输入

posted @ 2021-01-05 01:54  acmloser  阅读(64)  评论(0编辑  收藏  举报