POJ2912 Rochambeau

题意

Language:
Rochambeau
Time Limit: 5000MS Memory Limit: 65536K
Total Submissions: 5783 Accepted: 1966

Description

N children are playing Rochambeau (scissors-rock-cloth) game with you. One of them is the judge. The rest children are divided into three groups (it is possible that some group is empty). You don’t know who is the judge, or how the children are grouped. Then the children start playing Rochambeau game for M rounds. Each round two children are arbitrarily selected to play Rochambeau for one once, and you will be told the outcome while not knowing which gesture the children presented. It is known that the children in the same group would present the same gesture (hence, two children in the same group always get draw when playing) and different groups for different gestures. The judge would present gesture randomly each time, hence no one knows what gesture the judge would present. Can you guess who is the judge after after the game ends? If you can, after how many rounds can you find out the judge at the earliest?

Input

Input contains multiple test cases. Each test case starts with two integers N and M (1 ≤ N ≤ 500, 0 ≤ M ≤ 2,000) in one line, which are the number of children and the number of rounds. Following are M lines, each line contains two integers in [0, N) separated by one symbol. The two integers are the IDs of the two children selected to play Rochambeau for this round. The symbol may be “=”, “>” or “<”, referring to a draw, that first child wins and that second child wins respectively.

Output

There is only one line for each test case. If the judge can be found, print the ID of the judge, and the least number of rounds after which the judge can be uniquely determined. If the judge can not be found, or the outcomes of the M rounds of game are inconsistent, print the corresponding message.

Sample Input

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

Sample Output

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

Source

Baidu Star 2006 Preliminary
Chen, Shixi (xreborner) living in http://fairyair.yeah.net/

分析

参照ygeloutingyu的题解。

感觉此题的题意有点模糊,加上样例才勉强看懂;如果能唯一确定裁判的编号,按照格式输出编号和能确定裁判的最少轮数,如果存在一个裁判但不能确定的话输出Can not determine,如果由输入得到有多个裁判或者一个裁判都没有,那么输出Impossible; 如果顺着题目的思路去想的话,因为裁判手势可以是任意的,很难确定编号之间的相对关系;又因为除了裁判外其余人的手势是不变的,那么我们一定可以将除裁判外的人分成三组(可以有空组);想到这里我们可以发现,如果我们假设某个编号为裁判,如果除了它外其余人的关系没有矛盾,那么它就可能是裁判;此题的数据不大, 那么只要我们枚举每一个节点,假设其为裁判,如果我们得到的可能为裁判的节点唯一,那么它就是裁判,如果得到可能为裁判的节点有多个,那么就不能确定裁判,如果可能为裁判的节点一个都没有,就是Impassible啦~

现在我们已经确定的了三种情况,剩下能确定裁判的时候还要输出最少几行能确定,我们是通过排除法来确定裁判编号的,枚举每个编号为裁判,一但在某一行输入中出现矛盾,我们就确定它不是裁判,那么n-1个出现矛盾的枚举中出现矛盾最晚的那个行数即为我们能确定裁判所需的最少行数啦(因为我们要排除n-1个编号才能确定裁判的编号嘛)

时间复杂度\(O(n^2 \log n)\)

代码

#include<iostream>
#include<cstring>
const int N=2001;
int n,m,a[N],b[N],fa[N],d[N],p[N];
char c[N];
int get(int x){
    if(fa[x]==x) return x;
    int root=get(fa[x]);
    d[x]=(d[x]+d[fa[x]])%3;
    return fa[x]=root;
}
bool work(int x,int y,int k){
    int fx=get(x),fy=get(y);
    if(fx==fy) return (d[x]+k)%3!=d[y]?0:1;
    fa[fy]=fx,d[fy]=(d[x]+3-d[y]+k)%3;
    return 1;
}
bool pd(int x){
    if(c[x]=='='&&!work(a[x],b[x],0)) return 1;
    if(c[x]=='<'&&!work(a[x],b[x],1)) return 1;
    if(c[x]=='>'&&!work(b[x],a[x],1)) return 1;
    return 0;
}
void Rochembeau(){
    for(int i=0;i<m;++i) scanf("%d%c%d",a+i,c+i,b+i);
    memset(p,0,sizeof p);
    int cnt=0,num=0;
    for(int i=0;i<n;++i){
        for(int j=0;j<n;++j) fa[j]=j;
        memset(d,0,sizeof d);
        bool flag=0;
        for(int j=0;j<m;++j)if(a[j]!=i&&b[j]!=i&&pd(j)){
            flag=1,p[i]=j+1; // base 0
            break;
        }
        if(!flag) num=i,++cnt;
    }
    if(!cnt) puts("Impossible");
    else if(cnt==1){
        int ans=0;
        for(int i=0;i<n;++i)
            if(i!=num&&p[i]>ans) ans=p[i];
        printf("Player %d can be determined to be the judge after %d lines\n",num,ans);
    }
    else puts("Can not determine");
}
int main(){
//  freopen(".in","r",stdin),freopen(".out","w",stdout);
    while(~scanf("%d%d",&n,&m)) Rochembeau();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/autoint/p/10660327.html
POJ