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;
}
例如:输入如下
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;
}
相关文章推荐
- poj 1029 False coin
- POJ 1029 False coin 笔记 G++
- POJ 1029--False coin
- 【模拟】Poj1029 False Coin
- poj 1029 确定唯一假币
- POJ 1013 1029 判断假币
- poj1029 模拟
- 1029 False coin
- POJ 1835 大模拟
- POJ 2996 Help Me with the Game(模拟)
- poj 1002 487-3279 ((含易错点、测试数据) 简单模拟 )
- poj1573(模拟)
- POJ 2105 IP Address(简单模拟)
- poj1053 模拟
- poj 1068 Parencodings(模拟)
- poj 2106 Boolean Expressions(模拟)
- POJ 2069 Super Star(模拟退火,最小球覆盖)
- POJ --3045--Cow Acrobats(贪心模拟)
- poj 3750 小孩报数问题(模拟)
- POJ 1068 Parencodings(模拟)