题目:
有N个硬币,经过K次称重,找出不一样重的假币。
每次称重,要求称两边硬币数一样,结果用<,>,=表示。
思路:
代码非原创,链接:
http://blog.csdn.net/dellaserss/article/details/8008329
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int main(){
int n,k,p,i,j,mark;
int flag[1001],t1[501],t2[501],temp[1001];
bool less[1001],more[1001];
char ch[10];
while(scanf("%d%d",&n,&k)!=EOF){ //输入N,K
memset(flag,-1,sizeof(flag)); //flag[i]=-1,则硬币i有嫌疑
memset(less,0,sizeof(less)); //less[i]=1,则硬币在轻的那头出现过
memset(more,0,sizeof(more)); //more[i]=1,则硬币在重的那头出现过
for(i=1;i<=k;i++){ //循环输入K次称重记录
scanf("%d",&p); //两边各放p个硬币
for(j=1;j<=p;j++) scanf("%d",&t1[j]);//左边硬币放t1[]
for(j=1;j<=p;j++) scanf("%d",&t2[j]);//右边硬币放t2[]
scanf("%s",ch); //称重结果:<,>,=
if(ch[0]=='=') //=:两边的硬币都没有嫌疑
for(j=1;j<=p;j++){ //取消嫌疑
flag[t1[j]]=0;
flag[t2[j]]=0;
}
else{ //<,>:嫌疑币就在里面
memset(temp,0,sizeof(temp));
for(j=1;j<=p;j++){ //temp[i]=1,表示有嫌疑
temp[t1[j]]=1;
temp[t2[j]]=1;
}
if(ch[0]=='>'){ //>
for(j=1;j<=p;j++) more[t1[j]]=1; //处于重(轻)的嫌疑币在more[i](less[i])=1
for(j=1;j<=p;j++) less[t2[j]]=1;
}
else{ //<
for(j=1;j<=p;j++) less[t1[j]]=1; //处于重(轻)的嫌疑币在more[i](less[i])=1
for(j=1;j<=p;j++) more[t2[j]]=1;
}
for(j=1;j<=n;j++){ //归纳此次称重
if(!temp[j]) flag[j]=0; //不在此次称重出现的,就没有嫌疑
if(more[j]&&less[j]) flag[j]=0; //忽轻忽重的硬币,就没有嫌疑
}
}
}
for(mark=0,i=1;i<=n;i++) //总结结果
if(flag[i]==-1){ //此币还有嫌疑
if(mark!=0){ //有多个嫌疑人,此题判断不了
mark=0;
break;
}
else
mark=i; //标记有嫌疑的币
}
printf("%d\n",mark); //输出结果
}
return 0;
}