题目描述
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;
}