算法-查找-赌徒

题目描述

N个赌徒一起决定玩一个游戏:
游戏刚开始的时候,每个赌徒把赌注放在桌上并遮住,侍者要查看每个人的赌注并确保每个人的赌注都不一样。如果一个赌徒没钱了,则他要借一些筹码,因此他的赌注为负数。假定赌注都是整数。
最后赌徒们揭开盖子,出示他们的赌注。如果谁下的赌注是其他赌徒中某3个人下的赌注之和,则他是胜利者。如果有多于一个胜利者,则下的赌注最大的赌徒才是最终的胜利者。
例如,假定赌徒为:Tom、Bill、John、Roger和Bush,他们下的赌注分别为:2、3、5、7和12 。因此最终获胜的是Bush(并且没有其他人是胜利者),因为他下的赌注为12,而其他的人下的赌注之和也等于12:2+3+7=12。

输入

输入文件中包含了多组赌徒下的赌注。每组赌注的数据第1行是一个整数n,1<=n<=1000,代表赌徒的个数,然后是他们下的赌注,每个人的赌注占一行,这些赌注各不相同,并且范围是[-536870912,+536870911]。输入文件的最后一行为0,代表输入结束。

输出

对每组赌注,输出胜利者下的赌注,如果没有解,则输出“no solution”。

样例输入 

5
2 
3 
5 
7 
12
5
2 
16 
64 
256 
1024
0

样例输出 

12
no solution

思路分析 

枚举,即从最大的赌注开始,看是否存在一个赌注是其他3个不同赌注之和。这个过程需要用四重循环实现。在排序的序列中,从后往前取赢家的序号i,这样计算的结果自然是赌注最大的赢家。三个赌徒的编号,至少有一个编号在赢家的前面(j),由于存在负数,另外两个赌徒的编号,就有可能在赢家编号的后面。

代码实现

#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace std;

int compare(const void*a,const void*b)
{
	return *(int*)a - *(int*)b;
}

int main()
{
	int n,i,j,k,p,b;
	int a[1000];
	while(cin>>n){
		if(n==0)break;
		for(i=0;i<n;i++){
		    cin>>a[i];
	    }
	    int flag=0;
	    qsort(a,n,sizeof(a[0]),compare);  //先对赌注进行排序
	    for(i=n-1;i>0;i--){              //从后往前取赢家的编号
		    for(j=0;j<n&&j!=i;j++){
			    for(k=j+1;k<n&&k!=j;k++){        //先枚举两个赌徒的赌注j,k
				    b=a[i]-a[k]-a[j];
				    for(p=k+1;p<n&&p!=k;p++){       //看假设的第三个赌注是否存在
					    if(b==a[p]){
					        cout<<a[i]<<endl;
					        flag=1;
					        break;
					    }
				    }
				    if(flag==1)break;
			    }
			    if(flag==1)break;
		    }
		    if(flag==1)break;
	    }
	    if(flag==0)cout<<"no solution"<<endl;
	}
	return 0;
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值