HDU1029 False coin

                                                                                                                                        False coin
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 15838   Accepted: 4408

Description

The "Gold Bar"bank received information from reliable sources that in their last group of N coins exactly one coin is false and differs in weight from other coins (while all other coins are equal in weight). After the economic crisis they have only a simple balance available (like one in the picture). Using this balance, one is able to determine if the weight of objects in the left pan is less than, greater than, or equal to the weight of objects in the right pan.
In order to detect the false coin the bank employees numbered all coins by the integers from 1 to N, thus assigning each coin a unique integer identifier. After that they began to weight various groups of coins by placing equal numbers of coins in the left pan and in the right pan. The identifiers of coins and the results of the weightings were carefully recorded.
You are to write a program that will help the bank employees to determine the identifier of the false coin using the results of these weightings.

Input

The first line of the input file contains two integers N and K, separated by spaces, where N is the number of coins (2<=N<=1000 ) and K is the number of weightings fulfilled (1<=K<=100). The following 2K lines describe all weightings. Two consecutive lines describe each weighting. The first of them starts with a number Pi (1<=Pi<=N/2), representing the number of coins placed in the left and in the right pans, followed by Pi identifiers of coins placed in the left pan and Pi identifiers of coins placed in the right pan. All numbers are separated by spaces. The second line contains one of the following characters: '<', '>', or '='. It represents the result of the weighting:
'<' means that the weight of coins in the left pan is less than the weight of coins in the right pan,
'>' means that the weight of coins in the left pan is greater than the weight of coins in the right pan,
'=' means that the weight of coins in the left pan is equal to the weight of coins in the right pan.

Output

Write to the output file the identifier of the false coin or 0, if it cannot be found by the results of the given weightings.

Sample Input

5 3 2 1 2 3 4 < 1 1 4 = 1 2 5 =

Sample Output

3

Source

Northeastern Europe 1998



解题思路:本题为模拟逻辑题,只要想通怎么确定硬币真假即可解得。

在称量中,有3种情况,> ,< =,其实,总体的情况只有两种,天平平行还是不平行。

(1)若天平是平行的,毫无疑问,所有参与本次称量的硬币都是真硬币。因为题目说了,假硬币只有一个,且真硬币的质量都相等。

(2)若天平不平行,就要分两边讨论了。若硬币在重的一边且尚未确定真假,如果该硬币在以前的称量中曾经出现在轻的一边,则该硬币可以确定为真硬币(状态置为102)。因为同一个硬币的重量是不变的,曾出现在轻的一边,后面又出现在重的一边,只能说,致使天平倾斜的硬币不是它,所以,该硬币是真的。否则记录它曾经出现在重的一边(状态++,置为正值)。对于在本次称量中处于轻的一边的硬币,同理处理即可。

注意:如果出现情况(2),有一个隐秘的信息一定要挖出来,银行说了,假硬币只有1个。若出现情况(2),表示,那个质量和真硬币不同的假硬币,已经出现在称量中了。也就是说,所有没有参与本次称量的硬币,都能确定是真的。

最后,逐个检索硬币的状态值,若值为102,即该硬币已确定为真硬币。否则,表示该硬币尚未确定真假。若未确定真假的硬币只有一个,则说明该硬币就是假硬币,输出该硬币的编号。否则,无法确定假硬币,输出“0”


#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int main() {     int co[1005];    //记录硬币情况,在称量后记录称量结果,     int n,k,i,j,x,bl[203];     char a[3];  //用于读入符号     while(scanf("%d%d",&n,&k)!=EOF)     {         int no=0;         memset(co,0,sizeof(co));   //状态记录数组置零         for(j=0;j<k;j++)         {             scanf("%d",&x);  //读入天平两遍硬币的个数             x*=2;             for(i=0;i<x;i++)                 scanf("%d",&bl[i]);   //读入所有参加称量的硬币号码             scanf("%s",a);   //读入符号,a[0]处存储的就是所读入夫人符号             if(a[0]=='=')   //若天平是平的,所有参与称量的硬币都是真的                 for(i=0;i<x;i++)                     co[bl[i]]=102;    //状态标记置为102,表示该硬币i已经检测过关,为真硬币             else if(a[0]=='<')  //若天平是右倾的             {                 no++;                 x/=2;                 for(i=0;i<x;i++)   //天平左边的硬币相对比较轻                 {                     if(co[bl[i]]!=102)   //如果该硬币为确定为真硬币                     {                         if(co[bl[i]]>0)   //若该硬币在前面的称量中曾经重过,则它是真的硬币(同一个硬币质量是不会变的)                             co[bl[i]]=102;                         else co[bl[i]]--;   //否则,记录为有有一次称量中,硬币在轻的一方                     }                 }                 x=2*x;                 for(i=x/2;i<x;i++)        //天平右边的硬币相对比较重                 {                     if(co[bl[i]]!=102)//如果该硬币为确定为真硬币                     {                         if(co[bl[i]]<0) //若该硬币在前面的称量中曾经轻过,则它是真的硬币(同一个硬币质量是不会变的)                             co[bl[i]]=102;                         else                             co[bl[i]]++;//否则,记录为有有一次称量中,硬币在重的一方                     }                 }                 int u;                 for(i=1;i<=n;i++)//由于假硬币只有一枚,出现了天平不平衡的情况,所有未参与本次称量的硬币都是真硬币                 {                     for(u=0;u<x;u++)                     {                         if(i==bl[u])                         break;                     }                     if(u==x)                         co[i]=102;                 }             }             else if(a[0]=='>')             {                 no++;                 for(i=x/2;i<x;i++)                 {                     if(co[bl[i]]!=102)                     {                         if(co[bl[i]]>0)                             co[bl[i]]=102;                         else co[bl[i]]--;                     }                 }                 x/=2;                 for(i=0;i<x;i++)                 {                     if(co[bl[i]]!=102)                     {                         if(co[bl[i]]<0)                             co[bl[i]]=102;                         else                             co[bl[i]]++;                     }                 }                 x*=2;                 int u;                 for(i=1;i<=n;i++)                 {                     for(u=0;u<x;u++)                     {                         if(i==bl[u])                         break;                     }                     if(u==x)                         co[i]=102;                 }             }         }         int j=0;         for(i=1;i<=n;i++)         {             if(co[i]!=102)    //若硬币i不能确定为真硬币,则它可能是假的             {                 if(j==0)                      j=i;                 else     //若在这个不能确定真假的硬币之前,有硬币是不能确定真假的,则无法确定哪个是假硬币                 {                     j=0;                     break;                 }             }         }         printf("%d\n",j);     }     return 0; } 


你可能感兴趣的:(模拟,逻辑,挖掘条件)