K - Rochambeau - poj2912(类似食物链)

一群小孩玩一个简单石头布布游戏,这些小孩会分成三组(组内可能没有人)+一个自由人(比翻译成裁判合理多了),同一组的小孩只会出同一种手势(不会变的),不过裁判可以出任意的手势,这些小孩能就会相互猜拳玩,A>B代表A赢B, <代表输, =代表平了,给你这些小孩玩游戏的结果,问你能不能找到那个自由人,如果找不出来,就输出Can not determine,如果发现不可能有这样的结果,除非有不止一个自由者那就输出Impossible,如果就一个自由者,那就输出这个自由者,和最先能判断这个自由者的位置的行号。。。

///////////////////////////////////

跟食物链差不多,查找自由者可以枚举每个人,比较简单就不说了

#include<iostream>
#include<algorithm>
#include<stdio.h>
#include<math.h>
#include<string.h>
#include<queue>
#include<stack>
using namespace std;

const int maxn = 505;

int f[maxn], val[maxn];
//0代表同类, 1代表赢, 2代表输
struct node{int u, v, rel;}data[maxn*4];

int Find(int x)
{
    int k = f[x];
    if(f[x] != x)
    {
        f[x] = Find(f[x]);
        val[x] = (val[x]+val[k])%3;
    }

return f[x];
}
//如果k是裁判是否有矛盾产生,有返回产生矛盾的行数, 没有返回-1
int Solve(int k, int N, int M)
{//这里跟食物链一样的
    int i, u, v, ru, rv;

for(i=0; i<N; i++)
        f[i] = i, val[i]=0;
    for(i=0; i<M; i++)
    {
        u = data[i].u, v = data[i].v;
        if(u != k && v != k)
        {
            ru = Find(u), rv = Find(v);

if(ru == rv && (val[v]+data[i].rel)%3 != val[u] )
                return i;
            f[ru] = rv;
            val[ru] = (data[i].rel-val[u]+val[v]+3)%3;
        }
    }

return -1;
}

int main()
{
    int i, N, M;

while(scanf("%d%d", &N, &M) != EOF)
    {
        char ch;

for(i=0; i<M; i++)
        {
            scanf("%d%c%d", &data[i].u, &ch, &data[i].v);
            if(ch == ‘=‘)
                data[i].rel = 0;
            else if(ch == ‘>‘)
                data[i].rel = 1;
            else
                data[i].rel = 2;
        }

int p = Solve(-1, N, M);
        
        //没有矛盾产生,无法判断出谁是裁判
        if(N != 1 && p == -1)
            printf("Can not determine\n");
        else if(N == 1)//只有一个人,只能是裁判
            printf("Player 0 can be determined to be the judge after 0 lines\n");
        else
        {
            int k=0, q, j;//k记录有多少个可以担任裁判

for(i=0; i<N; i++)
            {
                j = Solve(i, N, M);
                if(j == -1)
                    k++, q = i;
                else
                    p = max(p, j);//因为要求可以最近的看出裁判的地方,其实就是别的点产生矛盾最远的地方
                if(k > 1)
                    break;
            }

if(k == 0)
                printf("Impossible\n");
            else if(k > 1)
                printf("Can not determine\n");
            else
                printf("Player %d can be determined to be the judge after %d lines\n", q, p+1);
        }
    }

return 0;
}

时间: 2024-10-14 05:28:56

K - Rochambeau - poj2912(类似食物链)的相关文章

[LeetCode] K-th Smallest in Lexicographical Order 字典顺序的第K小数字

Given integers n and k, find the lexicographically k-th smallest integer in the range from 1 to n. Note: 1 ≤ k ≤ n ≤ 109. Example: Input: n: 13 k: 2 Output: 10 Explanation: The lexicographical order is [1, 10, 11, 12, 13, 2, 3, 4, 5, 6, 7, 8, 9], so

K-Means(K均值)、GMM(高斯混合模型),通俗易懂,先收藏了!

1. 聚类算法都是无监督学习吗? 什么是聚类算法?聚类是一种机器学习技术,它涉及到数据点的分组.给定一组数据点,我们可以使用聚类算法将每个数据点划分为一个特定的组.理论上,同一组中的数据点应该具有相似的属性和/或特征,而不同组中的数据点应该具有高度不同的属性和/或特征.聚类是一种无监督学习的方法,是许多领域中常用的统计数据分析技术. 常用的算法包括K-MEANS.高斯混合模型(Gaussian Mixed Model,GMM).自组织映射神经网络(Self-Organizing Map,SOM)

*并查集的题*

POJ 1182 食物链http://acm.pku.edu.cn/JudgeOnline/problem?id=1182题目告诉有3种动物,互相吃与被吃,现在告诉你m句话,其中有真有假,叫你判断假的个数(如果前面没有与当前话冲突的,即认为其为真话)这题有几种做法,我以前的做法是每个集合(或者称为子树,说集合的编号相当于子树的根结点,一个概念)中的元素都各自分为A, B, C三类,在合并时更改根结点的种类,其他点相应更改偏移量.但这种方法公式很难推,特别是偏移量很容易计算错误.下面来介绍一种通用

noip2010关押罪犯

题目链接:传送门 题目思路:并查集高级应用(类似食物链那道题),主要是维护两个集合(监狱里犯人的关系),同一个集合里的是朋友,否则是敌人,如果敌人在同一间监狱里, 则最小的最大冲突值求出. #include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <cstring> #include &

Go语言核心之美 3.2-Map

哈希表是一种非常好用.适用面很广的数据结构,是key-value对的无序集合.它的key是唯一的,通过key可以在常数复杂度时间内进行查询.更新或删除,无论哈希表有多大. Go语言的map类型就是对哈希表的引用,表示为map[key]value.map中所有的key都是相同的类型,所有的value也是相同的类型,不过key和value可以是不同的类型.key代表的数据类型必须支持==和!=运算符,这样map才能检测指定的key是否已经存在.虽然浮点数支持相等运算符,但是正如我们在第二章提到的,浮

BZOJ 3196 二逼平衡树 线段树+treap

题意:链接 方法:线段树+treap的模板题 题解: 首先是对于整个树的定义,其实treap部分并没有什么区别,只不过是单root改变为多root而已. #include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #define lson l,mid,rt<<1 #define rson mid+1,

SCOI2015题解 &amp;&amp; 考试小结

Day1: 第一题:裸地二分+网络流:二分答案,连接将每行每列拆成点,对于满足答案的格子行列连边,看是否流量是否大于t即可,可惜第k大看成了第k小,然后100分就没了. 第二题:倍增,考虑贪心算法,就是考虑选了当前的线段,下一次选的必定是左端点小于当前右端点,右端点尽量靠后的线段,因此在化环为链后,预处理每一个线段的后继状态,当我门选了一条线段后,剩下的选择一定按照刚才的思路选择,所以像lca一样倍增处理每个线段跳2^i次后的位置,对于每一个询问,O(logn)时间向后跳直到覆盖所有区间. 第三

HDU2879 HeHe 数论积性函数

题目名字有点搓,做题时没做出来,学长他们做出了,发现跟网上题解的思路没太大区别,网上所有题解的分析也都转自同一个地方,看样子这道题目不是那么好想的,没办法按照解析画了半天,计算器按了半天,理解了,自己敲出来了,觉得值得留念,打算再刷几道这样的 转自:http://blog.csdn.net/kksleric/article/details/8096914 定义:对于正整数n的一个算术函数 f(n),若f(1)=1,且当a,b互质时f(ab)=f(a)f(b),在数论上就称它为积性函数.若对于某积

bzoj1706: [Usaco2007 Nov]relays 奶牛接力跑 (Floyd+新姿势)

题目大意:有t(t<=100)条无向边连接两点,求s到e刚好经过n(n<=10^7)条路径的最小距离. 第一反应分层图,但是一看n就懵逼了,不会写.看了题解之后才知道可以这么玩... 首先有100条边最多200个点,但点编号到1000,所以离散化一下. 任何一个正整数都能用2的幂相加得到,所以先把n转变成2进制来看,按位考虑.dist[i][j][k]表示刚好经过2^i条边从j到k的最短距离,则dist[i,j,k]=min{dist[i-1][j][l]+dist[i-1][l][k]}.用