描述

This problem is based on the game of Black Vienna. In this version there are three players and 18 cards labeled A-R. Three of the cards are set aside (hidden) and form the "Black Vienna" gang. The remaining cards are shuffled and dealt to the players so that each player has 5 cards. Players never reveal their cards to each other. There is a separate deck of "interrogation cards" which contain three distinct letters in ascending order, like ACG or BHR.  Turns rotate through players 1, 2, and 3. On each player's turn, that player selects an interrogation card, puts it face up in front of another player, and that other player must indicate the total number of these cards being held, without saying which ones.  All players see the result of the "interrogation". The play continues until a player deduces the three cards in the "gang".     For example, suppose the cards are distributed as follows, and the game then proceeds:

Player 1: DGJLP; Player 2: EFOQR; Player 3: ACHMN;  Gang: BIK Turn 1:  Player 1 interrogates player 2 with BJK; answer 0

Turn 2:  Player 2 interrogates player 3 with ABK; answer 1 Turn 3:  Player 3 interrogates player 2 with DEF; answer 2

Turn 4: Player 1 interrogates player 2 with EIL; answer 1 Turn 5:  Player 2 interrogates player 3 with FIP; answer 0

Turn 6:  Player 3 interrogates player 1 with GMO; answer 1 Turn 7:  Player 1 interrogates player 2 with OQR; answer 3

Turn 8:  Player 2 interrogates player 3 with ADQ; answer 1 Turn 9:  Player 3 interrogates player 1 with EGJ; answer 2

In fact, the game does not need to get to turn 9.  With enough thought, player 1 can deduce after turn 8 that the gang is BIK.  It is your job to analyze records of games and deduce the earliest time that the gang could be determined for sure.

输入

The input will consist of one to twelve data sets, followed by a line containing only 0.   The first line of a dataset contains the number, t, of turns reported, 2 ≤ t ≤ 15.  The next line contains four blank separated strings for the hands of players 1, 2, and 3, followed by the cards for the gang. The remaining t lines of the data set contain the data for each turn in order.  Each line contains three blank separated tokens:  the number of the player interrogated, the string of interrogation letters, and the answer provided. All letter strings will contain only capital letters from A to R, in strictly increasing alphabetical order.  The same interrogation string may appear in more than one turn of a game.

输出

There is one line of output for each data set.  The line contains the single character "?" if no player can be sure of the gang after all the turns listed.  If a player can determine the gang, the line contains the earliest turn after which one or more players can be sure of the answer.

样例输入

9

DGJLP EFOQR ACHMN BIK

2 BJK 0

3 ABK 1

2 DEF 2

2 EIL 1

3 FIP 0

1 GMO 1

2 OQR 3

3 ADQ 1

1 EGJ 2

3

ABCDE FGHIJ KLMNO PQR

3 BKQ 1

1 ADE 3

2 CHJ 2

0

样例输出

8

?

include<iostream>
using namespace std; const int PLAYERS = 3, // check against final problem statement!
MAX_TURNS = 15, HAND = 5, HID = 3, UNK = HID+HAND*(PLAYERS-1);
int turns; char quest[MAX_TURNS][3+1], // interrogations
hand[PLAYERS + 1][5+1], //actual hands, gang at end
maybe[PLAYERS + 1][HAND+1]; //possible hands, gang char unk[UNK]; // letters not in one player's hand
int who[MAX_TURNS], // who interrogated
matches[MAX_TURNS], // matches in interogation
used[PLAYERS+1]; // amount of maybe hand filled
int solved; // max turns needed for current player for comb. so far int Max(int a,int b);
void solve(int i,char unk[]);
int countConsistent(char choice[][HAND+1]);
int countDups(char a1[],char a2[]); int main()
{
//freopen("in.txt","r",stdin);
int i,j;
int bestSolved;
while(scanf("%d",&turns)!=EOF && turns>0)
{
for(i=0;i<=PLAYERS;i++)
scanf("%s",&hand[i]);
int t;
for(t=0;t<turns;t++)
{
scanf("%d",&who[t]);
who[t]--; // internal 0 based
scanf("%s",&quest[t]);
scanf("%d",&matches[t]);
}
bestSolved=MAX_TURNS;
int p;
char unkStr[18-5+1];
for(p=0;p<PLAYERS;p++)
{
memset(unkStr,'\0',sizeof(unkStr));
for(j=0;j<=PLAYERS;j++){
if(j!=p)
strcat(unkStr,hand[j]);
}
strcpy(maybe[p],hand[p]); // player knows own
used[p] = HAND; // no further characters to choose
solved = 0; // after recursion max turns to eliminate a maybe
solve(0,unkStr);
memset(maybe[p],'\0',sizeof(maybe[p]));
used[p]=0;
if(solved<bestSolved)
bestSolved=solved;
}
if(bestSolved<turns)
printf("%d\n",bestSolved+1);
else
printf("?\n");
}//end while
return 0;
}//end main() int Max(int a,int b)
{ return (a>b)?a:b; } // accumulate combinations recursively, check when one is complete
void solve(int i,char unk[])
{
if(i==(18-5)){ // assigned all choices, now check
if (maybe[PLAYERS][0] == unk[i-HID]) return; //match end gang char
solved = Max(solved, countConsistent(maybe));
}
else{
int j;
for(j=0;j<=PLAYERS;j++){
if((j<PLAYERS && used[j]<5) || (j==PLAYERS && used[j]<3)){ //add char to partial hand
maybe[j][used[j]]=unk[i];
used[j]++;
solve(i+1,unk);
used[j]--; // undo change before trying next player
}
}
}
} // return first inconsistent turn (0 based) or total turns if consistent
int countConsistent(char choice[][HAND+1])
{
int t=0;
while(t<turns &&
countDups(choice[who[t]],quest[t])==matches[t])
t++;
return t;
} int countDups(char a1[],char a2[])
{
int i,j;
int n=0;
for(i=0;i<5;i++){
for(j=0;j<3;j++)
if(a1[i]==a2[j])
n++;
}
return n;
}

  

1091-Black Vienna的更多相关文章

  1. [swustoj 1091] 土豪我们做朋友吧

    土豪我们做朋友吧(1091) 问题描述: 人都有缺钱的时候,缺钱的时候要是有个朋友肯帮助你,那将是一件非常幸福的事情.有N个人(编号为1到N),一开始他们互相都不认识,后来发生了M件事情,事情分为2个 ...

  2. ural 1091. Tmutarakan Exams 和 codeforces 295 B. Greg and Graph

    ural 1091 题目链接:http://acm.timus.ru/problem.aspx?space=1&num=1091 题意是从1到n的集合里选出k个数,使得这些数满足gcd大于1 ...

  3. [Swust OJ 1091]--土豪我们做朋友吧(并查集,最值维护)

    题目链接:http://acm.swust.edu.cn/problem/1091/ Time limit(ms): 1000 Memory limit(kb): 32768   人都有缺钱的时候,缺 ...

  4. ural 1091. Tmutarakan Exams(容斥原理)

    1091. Tmutarakan Exams Time limit: 1.0 secondMemory limit: 64 MB University of New Tmutarakan trains ...

  5. 51Nod 1091 线段的重叠(贪心+区间相关,板子题)

    1091 线段的重叠 基准时间限制:1 秒 空间限制:131072 KB 分值: 5         难度:1级算法题 X轴上有N条线段,每条线段包括1个起点和终点.线段的重叠是这样来算的,[10 2 ...

  6. PAT 乙级 1091 N-自守数 (15 分)

    1091 N-自守数 (15 分) 如果某个数 K 的平方乘以 N 以后,结果的末尾几位数等于 K,那么就称这个数为“N-自守数”.例如 3×92​2​​=25392,而 25392 的末尾两位正好是 ...

  7. nyoj 1091 还是01背包(超大数dp)

    nyoj 1091 还是01背包 描述 有n个重量和价值分别为 wi 和 vi 的物品,从这些物品中挑选总重量不超过W的物品,求所有挑选方案中价值总和的最大值 1 <= n <=40 1 ...

  8. 【PAT】1091 Acute Stroke(30 分)

    1091 Acute Stroke(30 分) One important factor to identify acute stroke (急性脑卒中) is the volume of the s ...

  9. ural 1091. Tmutarakan Exams(容斥)

    http://acm.timus.ru/problem.aspx? space=1&num=1091 从1~s中选出k个数,使得k个数的最大公约数大于1,问这种取法有多少种. (2<=k ...

随机推荐

  1. android之手工建立代码工程

    文件夹及文件架构: AndroidManifest.xml Android.mk res/layout/main.xml res/values/strings.xml src/com/liuzw/he ...

  2. 一些实用的js高级技巧

    技巧一之setTimeout. 应用案例:比如你想一个函数循环执行10次,怎么办?以前通常是先setInterval,然后clearInterval,技巧一就是克服这个问题 (function () ...

  3. 【转】Oracle - 数据库的实例、表空间、用户、表之间关系

    [转]Oracle - 数据库的实例.表空间.用户.表之间关系 完整的Oracle数据库通常由两部分组成:Oracle数据库和数据库实例. 1) 数据库是一系列物理文件的集合(数据文件,控制文件,联机 ...

  4. Activti跳过中间节点的helloworld实例程序

    http://blog.csdn.net/songzheng_741/article/details/17289633 此实例是一个最简单的在运行时人为动态改变流程运转的实例,意在为任意流.驳回等功能 ...

  5. asp.net服务器页面处理过程

    一.静态页面.动态页面区别 静态页面是服务端直接从硬盘里面读取然后发回去,动态页面就要创建这个页面类的对象,调用对象的方法,方法里面什么就发回什么.浏览器请求asp.net页面实际是请求asp.net ...

  6. python学习第二天:数字与字符串转换及逻辑值

    1.数字与字符串的转化     #1.数字转字符,使用格式化字符串:         *1.demo = ‘%d’  %  source         *2.%d整型:%f 浮点型 :%e科学计数 ...

  7. 牛客OJ——[编程题]A+B和C__如何输入多组测试数据(测试OK)

    几个要注意的地方: (1)Java OJ,必须将类名写成Main (2)关于如何输入多组测试数据,用二维数组去存储是一个方法,直接在while里面做也可以          但是如果  (3)关于整形 ...

  8. JS学习之表格的排序

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. cannot convert from '_TCHAR *' to 'char *'

    Reference: Why can't convert TCHAR* to char* Need to Use Multi-Byte Character Set in project's setti ...

  10. [转载]《STL源码剖析》阅读笔记之 迭代器及traits编程技法

    本文从三方面总结迭代器   迭代器的思想   迭代器相应型别及traits思想   __type_traits思想 一 迭代器思想 迭代器的主要思想源于迭代器模式,其定义如下:提供一种方法,使之能够依 ...