【算法设计与分析】8枚硬币及n枚硬币问题

问题描述

在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;
} 
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值