zoukankan      html  css  js  c++  java
  • POJ 2912 Rochambeau

    题意:有一些人玩石头剪刀布,其中有一个人(称其为裁判)可以出“石头”,“剪刀”,“布”中的任意一个,其他人永远只能出相同的一个。即有的人只能出剪刀,有的人只能出石头,有的人只能出布。进行了多次对决,每次只告诉你谁赢了(或者平手),不说谁出了什么。问能否判断出谁是裁判,裁判有多少个?若只有一个裁判,问在进行了多少次对决以后就能判断出裁判是谁。

    解法:首先,判断出裁判的方法是,若1,2,3号选手的结果出现了矛盾,则1,2,3号中必有一个人是裁判,

       (1)这个时候如果3,4号的对决结果出现矛盾,则判定3为裁判,然后还需要验证(即如果3为裁判,其他对决结果是不是不会有矛盾);

       (2)这个时候如果4,5号出现矛盾,则说明裁判不止一个人,与题设不符;

       (3)如果之后都再也没有出现矛盾,则说明不能判断出裁判是谁。

       所以,方法就是,枚举谁是裁判,判断是否所有不涉及到裁判的对决结果之间没有矛盾。如果只有一个裁判,还需要求进行了多少次对决以后就已经能判断出裁判是谁了。由以上结论不难看出,在整个枚举过程中,最大的出现矛盾的对决的编号数即为所求。

    tag:并查集,good

      1 /*
      2  * Author:  Plumrain
      3  * Created Time:  2013-11-28 19:23
      4  * File Name: DS-POJ-2912.cpp
      5  */
      6 #include <iostream>
      7 #include <cstdio>
      8 #include <vector>
      9 
     10 using namespace std;
     11 
     12 #define PB push_back
     13 
     14 struct node{
     15     int f, r;
     16 };
     17 
     18 int n, m, line;
     19 node p[505];
     20 char xn[2005];
     21 vector<int> ans;
     22 int an[2005], bn[2005];
     23 
     24 int find (int x)
     25 {
     26     if (x != p[x].f){
     27         int y = p[x].f;
     28         p[x].f = find(y);
     29         p[x].r = (p[x].r + p[y].r) % 3;
     30     }
     31     return p[x].f;
     32 }
     33 
     34 void merge(int a, int b, char xx, int t1, int t2)
     35 {
     36     int x;
     37     if (xx == '=') x = 0;
     38     else if (xx == '>') x = 1;
     39     else x = 2;
     40 
     41     p[t1].f = t2;
     42     p[t1].r = (3 - p[a].r + x + p[b].r) % 3; 
     43 }
     44 
     45 bool ok(int a, int b, char xx)
     46 {
     47     int x;
     48     if (xx == '=') x = 0;
     49     else if (xx == '>') x = 1;
     50     else x = 2;
     51     
     52     return x == ((p[a].r + 3 - p[b].r) % 3);
     53 }
     54 
     55 bool gao(int x)
     56 {
     57     for (int i = 0; i < n; ++ i){
     58         p[i].f = i;
     59         p[i].r = 0;
     60     }
     61     
     62     for (int i = 0; i < m; ++ i){
     63         if (an[i] == x || bn[i] == x) continue;
     64         
     65         int t1 = find(an[i]), t2 = find(bn[i]);
     66         if (t1 != t2)
     67             merge(an[i], bn[i], xn[i], t1, t2);
     68         if (t1 == t2)
     69             if (!ok(an[i], bn[i], xn[i])){
     70                 line = max(line, i + 1);
     71                 return 0;
     72             }
     73     }
     74     return 1;
     75 }
     76 
     77 int main()
     78 {
     79     while (scanf ("%d%d", &n, &m) != EOF){
     80         if (!m){
     81             if (n == 1) printf ("Player 0 can be determined to be the judge after 0 lines
    ");
     82             else printf ("Can not determine
    ");
     83             continue;
     84         }
     85 
     86         for (int i = 0; i < m; ++ i)
     87             scanf ("%d%c%d", &an[i], &xn[i], &bn[i]);
     88         
     89         ans.clear();
     90         line = 0;
     91         for (int i = 0; i < n; ++ i)
     92             if (gao(i)) ans.PB (i);
     93 
     94         int sz = ans.size();
     95         if (sz > 1) printf ("Can not determine
    ");
     96         else if (!sz) printf ("Impossible
    ");
     97         else printf ("Player %d can be determined to be the judge after %d lines
    ", ans[0], line);
     98     }
     99     return 0;
    100 }
    View Code
    ------------------------------------------------------------------
    现在的你,在干什么呢?
    你是不是还记得,你说你想成为岩哥那样的人。
  • 相关阅读:
    [NOI2019]回家路线(最短路,斜率优化)
    LOJ6686 Stupid GCD(数论,欧拉函数,杜教筛)
    Codeforces Global Round 4 题解
    CF908G New Year and Original Order(DP,数位 DP)
    [BJOI2019]光线(DP)
    CF1194F Crossword Expert(数论,组合数学)
    SPOJ31428 FIBONOMIAL(斐波那契数列)
    Codeforces Round 573 (Div.1) 题解
    [THUPC2018]弗雷兹的玩具商店(线段树,背包)
    数学基础
  • 原文地址:https://www.cnblogs.com/plumrain/p/POJ_2912.html
Copyright © 2011-2022 走看看