/*
所谓的蛮力法(也叫穷举法.暴力法)
我们假设i号金币是假的。
对各组记录进行比较, 如果假设和记录不矛盾, 有可能是假的
如果可能的假金币只有1个, 输出其编号; 否则, 输出0.
*/
#include "iostream"
#include "cstring"
#include "cstdio"
using namespace std;
int num[100][1001]; //存放称量记录
char s[1000]; //存放称量结果
/*
假设j号金币为假的与称量结果是否矛盾
s是称量记录, 其第一个元素师砝码个数
c是称量结果
*/
short jd(int j, int *s, char c){
int m, f, i;
m = s[0] << 1;
for(i =1, f = 1; i <= m && f;){
if(s[i] == j) //判断本次称量有无j好金币, 有则f = 0
f = 0;
else ++i;
}
//如果没有j号金币而天平不平衡, 或有j号金币而天平平衡, 则与假设矛盾
if(!f && c == '=' || f && c != '='){
return 0;
}
return 1;
}
int main(){
int iCase, n, k, i, j, flage = 0;
cin>> iCase; //测试例数
while(iCase--){
if(flage)
cout<<endl;
else
flage = 1;
cin >> n >> k;
memset(num, 0, sizeof(num));//初始化
memset(s, 0, sizeof(s));
for(i = 0; i < k; i++){ //接收数据
cin >> num[i][0];
int len = num[i][0] * 2;
for(j = 1; j <= len; j++){
cin >> num[i][j];
}
cin >> s[i];
}
int t, no;
for(i = 1, t = 0; i <= n; i++){ //第一个for循环对每一个金币遍历
for(j = 0; j < k && jd(i, num[j], s[j]); j++); //第二个for循环把每一组称量记录给函数jd, 判断i是否为假,
//如果j < k就结束了, 说明i金币为真
if(j < k) continue;
t++; //超过一个可能为假的金币, 那么 t > 1, 而这种情况最终会认为是无金币, 因为只有一个假金币
if(t > 1)
break;
no = i; // 如果 t == 1 , 那么记录编号
}
if( t != 1) //输出结果
cout<<0<<endl;
else
cout<<no<<endl;
}
return 0;
}
ZOJ 2034 False Coin
最新推荐文章于 2022-03-03 08:08:43 发布