D - C002 赌徒(Gamblers)

Problem Description

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

Input

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

Output

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

Sample Input

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

Sample Output

12
no solution

代码

#include <stdio.h>
#include <stdlib.h>

const int MAXN=1001;
int data[MAXN],n;   //赌徒们下的赌注及赌徒的人数

//排序函数的比较因子,升序排序
int cmp(const void *a, const void *b)
{
	return *(int *)a-*(int *)b;
}

int search(int x)  //在data数组中查找x,如果查找到,返回相应的下标,否则返回-1,采用二分搜索法
{
	int low=0,high=n-1,mid;			//计算左右边界
	while (low<=high)
	{
		mid = (low+high)/2;			//中间位置
		if (data[mid]==x) return mid;//找到了,返回位置序号
		if (data[mid]>x) high = mid-1;
		if (data[mid]<x) low = mid+1;
	}
	return -1;						//没有找到
}

//枚举算法,求解答案
void work()
{
	qsort(data,n,sizeof(data[0]),cmp);//从小到大排序
	int i,j,k,m;
	//枚举查找
	for(i=n-1;i>=0;i--)					//赢家从序列的后面取,确保是最大的
	{
		for(j=0;j<n;j++)
		{
			if(i==j)  continue;
			for(k=j+1;k<n;k++)
			{
				if(i==k) continue;
				m=search(data[i]-data[j]-data[k]);
				//存在第4个人下的赌注为data[i]-data[j]-data[k]
				//并且这个人不是i,j,也不是k,则i就是胜利者
				if(m>=0 && m!=i && m!=j && m!=k)
				{
					printf("%d\n",data[i]);
					return ;
				}
			}
		}
	}
	printf("no solution\n");
}

int main()
{
//	freopen("in.txt","r",stdin);
	while(scanf("%d",&n))
	{
		int i;
		if(n==0) break;
		for(i=0;i<n;i++)
			scanf("%d",&data[i]);
		work();
	}
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值