POJ - 2912 Rochambeau(带权并查集+暴力)

该博客介绍了POJ 2912题目的详细解题过程,探讨如何通过带权并查集和暴力枚举方法来判断在剪刀石头布游戏中哪位玩家可能是裁判,并在多少轮后可以确定裁判身份。

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

题目大意:给出N个人剪刀石头布的结果,问能否判断哪个人是裁判,在第几个回合可以判定

解题思路:如果这个人是裁判的话,那么去掉它的话,对结果是不影响的
所以可以暴力枚举一下谁当裁判,然后判断一下

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define maxn 510
#define maxm 2010
int f[maxn], r[maxn], p1[maxm], p2[maxm], sign[maxm], n, m;

void input() {
    char c;
    for(int i = 0; i < m; i++) {
        scanf("%d",&p1[i]);
        while((c = getchar()) == ' ');
        scanf("%d",&p2[i]);
        if(c == '<')
            sign[i] = 1;
        else if(c == '>')
            sign[i] = 2;
        else
            sign[i] = 0;
    }
}

void init() {
    for(int i = 0; i <= n; i++) {
        f[i] = i;
        r[i] = 0;
    }
}

int find(int x) {
    if(x == f[x])
        return x;
    int t = find(f[x]);
    r[x] = (r[x] + r[f[x]]) % 3;
    return f[x] = t;
}

void solve() {
    int ans = -1, line = 0;
    for(int i = 0; i < n; i++) {
        init();
        int tmp = -1, j;
        for(j = 0; j < m; j++) {
            int x = p1[j], y = p2[j];
            if(x == i || y == i)
                continue;
            int xx = find(x);
            int yy = find(y);
            if(xx == yy) {
                if( ((3 - r[y] + r[x]) % 3) != sign[j]) {
                    tmp = j + 1;
                    break;
                }
            }
            else {
                f[xx] = yy;
                r[xx] = (r[y] + sign[j] - r[x] + 3) % 3;
            }
        }
        if(j == m) {
            if(ans != -1) {
                printf("Can not determine\n");
                return ;
            }
            else 
                ans = i;
        }
        else 
            line = max(line,tmp);
    }
    if(ans == -1) 
        printf("Impossible\n");
    else
        printf("Player %d can be determined to be the judge after %d lines\n", ans, line);
}

int main() {
    while(scanf("%d%d", &n, &m) == 2){
        input();
        solve();
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值