您的位置:首页 > 其它

POJ 1029 False coin 找假币 模拟

2017-08-07 09:39 239 查看
题目:有N个硬币,里面有一个硬币是坏的,现在称了M次(称两边放数量一样的硬币)并把结果作为输入,根据称的结果判断第几号硬币是坏的。

例如:输入如下
5 3                  (5表示有5个硬币,3表示称了3次,下面依次是每次称的结果)
2 1 2 3 4         (2表示称的两边分别放两个硬币,分别是1、2和3、4)
<                     (1+2<3+4)
1 1 4               (1表示称的两边分别放一个硬币,分别是1和4)
=                     (1=4)
1 2 5               (1表示称的两边分别放一个硬币,分别是2和5)
=                     (2=5)

思路:

当两边一样重的时候,说明称量的硬币都是真的,对于这些硬币,我们直接做记号说明是真硬币。

当不一样重的时候,说明天平上肯定存在假硬币,但是我们不知道假硬币是在轻的一端还是重的一端。接下来这点很重要,天平不平衡了几次,假硬币肯定也出现了几次。所以对于不平衡时的称量,我们将称量的硬币出现的次数+1,注意,轻的一端和重的一端需要分开计数。最后我们比较天平不平衡的次数和每个硬币出现的次数,如果只有一个硬币称量的次数等于天平不平衡次数,说明该硬币就是假硬币。有多个时就无法判断出来。

#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<cstdio>
const int maxn=100005;
using namespace std;
int flag[maxn]; //记录硬币真假,1为真
int t[maxn]; //记录硬币原始数据
int w[maxn]; //记录硬币出现的次数,轻的和重的要分开记录,为正表示重的出现次数,负表示轻的出现次数
int main()
{
// freopen("E:\\ACM\\test.txt","r",stdin);
int N,K,p;
int total=0; //记录不等式出现出现次数
char c;
cin>>N>>K;
while(K--)
{
cin>>p;
for(int i=0;i<2*p;i++) cin>>t[i];
cin>>c;

if(c=='=') //为真
{
for(int i=0;i<2*p;i++) flag[t[i]]=1;
}
else if(c=='<') //左轻右重
{
++total;
for(int i=0;i<p;i++) w[t[i]]--;
for(int i=p;i<2*p;i++) w[t[i]]++;
}
else if(c=='>') //左重右轻
{
++total;
for(int i=0;i<p;i++) w[t[i]]++;
for(int i=p;i<2*p;i++) w[t[i]]--;
}

}
int count=0,pos=0;
for(int i=1;i<=N;i++)
{
if(flag[i]==0&&(w[i]==total||w[i]==-total)) //找每次都出现的假币
{
++count;
pos=i;
}
}
if(count!=1) puts("0");
else cout<<pos<<endl;

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  模拟 ACM POJ 1029