POJ2912(种类并查集)

本文解析了POJ2912题目,通过并查集算法解决石头剪刀布游戏中的裁判判断问题。介绍了并查集的使用方法,包括查找和合并操作,并展示了完整的代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

POJ2912

题意

n个人玩石头剪刀布的游戏,其中有一个人是裁判,要求将这些人分成三组,这三组可以为空,然后如果裁判为1个输出裁判为第几个人,在多少行就判断出来,如果裁判可能有多个,就输出"Can not determine",没有就输出"Impossible".

思路

种类并查集(雾),我之前都做的是扩展域并查集,然而我是看完题解才懂的,并查集貌似是满足以下图片的关系,图片参考的博客

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-q0RnU0rB-1570096016106)(C:\Users\Home\AppData\Roaming\Typora\typora-user-images\1570095540993.png)]

看着自己YY一下,感觉还挺有道理,主要是这个关系其实是构成一个环,石头>剪刀,剪刀>布,然后布>石头,然后取模就可以得到与父节点的关系.

代码

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
struct node{
    int x,y;
    char c;
}a[maxn];
int fa[maxn],rel[maxn];
int f(char c){
    if(c=='=') return 0;
    if(c=='<') return 1;
    if(c=='>') return 2;
}
int find(int x){
    if(x==fa[x]) return x;
    int fx=find(fa[x]);
    rel[x]=(rel[x]+rel[fa[x]])%3;
    return fa[x]=fx;
}
bool check(int x,int y,int flag){
    int fx=find(x),fy=find(y);
    if(fx!=fy){
        fa[fx]=fy;
        rel[fx]=(3+flag+rel[y]-rel[x])%3;
        return true;
    }
    else return flag==(3+rel[fx]+rel[x]-rel[y])%3;
}
int main(){
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        for(int i=1;i<=m;i++){
            scanf("%d%c%d",&a[i].x,&a[i].c,&a[i].y);
        }
        int ans=0,id,maxx=0;
        for(int i=0;i<n;i++){
            bool flag=0;
            for(int i=0;i<n;i++) fa[i]=i,rel[i]=0;
            for(int j=1;j<=m;j++){
                if(i==a[j].x||i==a[j].y) continue;
                if(!check(a[j].x,a[j].y,f(a[j].c))){
                    flag=1;
                    maxx=max(maxx,j);
                    break;
                }
            }
            if(!flag){
                id=i;
                ans++;
            }
        }
        if(ans>1) printf("Can not determine\n");
        else if(ans==1) printf("Player %d can be determined to be the judge after %d lines\n",id,maxx);
        else printf("Impossible\n");
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值