问题描述
在8枚外观相同的硬币中,有一枚是假币,并且已知假币和真币的重量不同,但不知假币是轻还是重,用天平来任意比较两组硬币。
8枚硬币问题
1.把8枚硬币分为3、3、2三个部分
2.先判断前两个部分是否相等,相等则拿第三部分分别和一枚真币进行比较
3.如果不相等,同时从前两部分各拿走一枚硬币并交换一对硬币进行比较,如
a+b+c>d+e+f:如果去掉cf,并交换be,即左右两边分别为a+e,d+b。
如果a+e>b+d,说明拿走的硬币和交换的硬币并没有影响结果,说明假币在ad中,拿ad分别和一枚真币(如c)进行比较,如果a>c说明a为较重的假币,否则d为较轻的假币;
如果a+e==b+d,说明假币在拿走的两枚硬币中,即在cf,拿cf和一枚真币(比如a)进行比较,若c>a则说明c为较重的假币,否则f为较轻的假币;
如果a+e<b+d,说明是交换的硬币导致平衡状态的改变,即假币存在于be中,拿be分别和一枚真币(如a)进行比较,如果b>a说明b为较重的假币,否则说明e为较轻的假币。
代码如下
#include<iostream>
#include<string>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
map<char,int> mp;
int sum(vector<int> v,int s,int e)
{
int total = 0;
for(int i=s;i<e;i++)
total += v[i];
return total;
}
void FakeCoinIndex(vector<int> v)
{
//int x1 = (v.size()+2)/3;
//int x2 = 2*x1;
int x1 = 3;
int x2 = 6;
if(sum(v,0,x1)>sum(v,x1,x2))
{
int temp = v[1];
v[1] = v[4];
v[4] = temp;
if(v[0]+v[1]==v[3]+v[4]) mp.insert(make_pair('H',2));
else if(v[0]+v[1]>v[3]+v[4]) mp.insert(make_pair('H',0));
else if(v[0]+v[1]<v[3]+v[4])
{
if(v[1]<v[0]) mp.insert(make_pair('L',4));
else mp.insert(make_pair('H',1));
}
}
else if(sum(v,0,x1)==sum(v,x1,x2))
{
if(v[6]>v[0]) mp.insert(make_pair('H',6));
else if(v[6]<v[0]) mp.insert(make_pair('L',6));
else if(v[7]>v[0]) mp.insert(make_pair('H',7));
else if(v[7]<v[0]) mp.insert(make_pair('L',7));
}
else
{
int temp = v[1];
v[1] = v[4];
v[4] = temp;
if(v[0]+v[1]==v[3]+v[4]) mp.insert(make_pair('L',2));
else if(v[0]+v[1]<v[3]+v[4]) mp.insert(make_pair('L',0));
else if(v[0]+v[1]>v[3]+v[4])
{
if(v[1]>v[0]) mp.insert(make_pair('H',4));
else mp.insert(make_pair('L',1));
}
}
}
int main()
{
int m,n;
cin >> n;
vector<int> v;
for(int i=0;i<n;i++)
{
cin >> m;
v.push_back(m);
}
FakeCoinIndex(v);
map<char,int>::iterator it = mp.begin();
cout << it->second <<" " << it->first <<endl;
return 0;
}
/*
8
1 1 2 1 1 1 1 1
8
1 1 1 1 0 1 1 1
*/
n枚硬币问题
遇到的问题:刚开始只写了n-m=1 和 n-m=2 的情况,但是如果假币正好属于n-m=1的情况就直接返回了,没有被处理,导致结果有纰漏。后来加上了n-m=3的情况。
代码如下:
#include<iostream>
#include<vector>
#include<map>
#include<string>
#include<algorithm>
using namespace std;
map<int,char> mp;
void CoinIndex(vector<int> v,int m,int n) //左闭右开
{
int mid = (m+n)/2;
if(n-m==1) return;
if(n-m==3)
{
if(v[m]==v[m+1])
{
if(v[m+2]>v[m]) mp.insert(make_pair(m+2,'H'));
else if(v[m+2]<v[m]) mp.insert(make_pair(m+2,'L'));
}
else if(v[m]<v[m+1])
{
if(v[m]==v[m+2]) mp.insert(make_pair(m+1,'H'));
else mp.insert(make_pair(m,'L'));
}
else if(v[m]>v[m+1])
{
if(v[m]==v[m+2]) mp.insert(make_pair(m+1,'L'));
else mp.insert(make_pair(m,'H'));
}
}
else if(n-m==2)
{
if(v[m]==v[m+1]) return;
else if(v[m]>v[m+1])
{
if(m!=0)
{
if(v[m]>v[0]) mp.insert(make_pair(m,'H'));
else mp.insert(make_pair(m+1,'L'));
}
else
{
if(v[m]>v[n]) mp.insert(make_pair(m,'H'));
else mp.insert(make_pair(m+1,'L'));
}
}
else if(v[m]<v[m+1])
{
if(m!=0)
{
if(v[m]<v[0]) mp.insert(make_pair(m,'L'));
else mp.insert(make_pair(m+1,'H'));
}
else
{
if(v[m]<v[n]) mp.insert(make_pair(m,'L'));
else mp.insert(make_pair(m+1,'H'));
}
}
}
CoinIndex(v,m,mid);
CoinIndex(v,mid,n);
}
int main()
{
int m,n;
while(cin >> n)
{
vector<int> v;
mp.clear();
for(int i=0;i<n;i++)
{
cin >> m;
v.push_back(m);
}
CoinIndex(v,0,n);
map<int,char>::iterator it = mp.begin();
cout << it->first << " " << it->second<<endl<<endl;
}
return 0;
}