这道题类似智力题,很有意思,意思就是从12个一样的钱币中找出一个未知重量的假币,称3次,给出结果,判断假币及其相对重量。
用模拟的方法很容易想到排除法,即分情况讨论:
当结果为even时,说明称上的几个钱币一定是真币
当结果为up时,说明其余的钱币一定是真币,并且左边钱币中有一个重的或者右边钱币中有一个轻的
当结果为down时,说明其余的钱币一定是真币,并且左边钱币中有一个轻的或者右边钱币中有一个重的
模拟的方法就是用一个数组记录每个钱币的状态,初始为-1,如果一定为真币记为0,如果可能较重记为2,如果可能较轻记为1,最后只要判断大于0的钱币一定为假币,而相应的状态表示它的相对重量。
可是实现时要考虑很多种细节,最重要的一点就是加一个记录上次状态的数组,因为如果上次判断一个钱币为真币,则不论下次结果如何,它还应当是真币;如果上次判断它可能较轻,而本次判断它可能较重,则它一定是真币!
下面是我实现的代码:
#include <iostream>
using namespace std;
int main(){
int n, i, j, bl, len;
int real[16], tmp[16];
char left[9], right[9], res[5];
char str[3][17]= {"ABCDEFGHIJKL","light","heavy"};
scanf("%d",&n);
while( n-- ){
memset(real,-1,sizeof(real));
for( i= 0; i< 3; i++ ){
scanf("%s%s%s",left,right,res);
bl= strcmp(res,"even");
len= strlen(left);
if( bl==0 ){ //even
for( j= 0; j< len; j++ )
real[left[j]-'A']= real[right[j]-'A']= 0;
}
else if( bl==-1 ){ //down
memcpy(tmp,real,sizeof(real));
memset(real,0,sizeof(real));
for( j= 0; j< len; j++ )
real[left[j]-'A']= 1, real[right[j]-'A']= 2;
for( j= 0; j< 16; j++ )
if( tmp[j]>=0 && tmp[j]!=real[j] ) real[j]= 0;
}
else{ //up
memcpy(tmp,real,sizeof(real));
memset(real,0,sizeof(real));
for( j= 0; j< len; j++ )
real[left[j]-'A']= 2, real[right[j]-'A']= 1;
for( j= 0; j< 16; j++ )
if( tmp[j]>=0 && tmp[j]!=real[j] ) real[j]= 0;
}
}
for( i= 0; i< 16; i++ )
if( real[i]> 0 )
printf("%c is the counterfeit coin and it is %s.\n",str[0][i],str[real[i]]);
}
return 0;
}
posted on 2009-06-22 17:36
古月残辉 阅读(1051)
评论(0) 编辑 收藏 引用 所属分类:
POJ