问题 A: 赌徒(折半枚举查找)

http://www.yyycode.cn/index.php/2020/05/16/%e9%97%ae%e9%a2%98-a-%e8%b5%8c%e5%be%92%e6%8a%98%e5%8d%8a%e6%9e%9a%e4%b8%be%e6%9f%a5%e6%89%be/


题目描述

有n个赌徒打算赌一局。规则是:
每人下一个赌注,赌注为非负整数,且任意两个赌注都不相同。胜者为赌注恰好是其余任意三个人的赌注之和的那个人。如果有多个胜者,我们取赌注最大的那个为最终胜者。
例如,A,B,C,D,E分别下赌注为2、3、5、7、12,最终胜者是E,因为12=2+3+7。

 

输入

输入包含多组测试数据。每组首先输入一个整数n(1<=n<=1000),表示赌徒的个数。
接下来n行每行输入一个非负整数b(0<=b<32768),表示每个赌徒下的赌注。
当n=0时,输入结束。

 

输出

对于每组输入,输出最终胜者的赌注,如果没有胜者,则输出no solution。

样例输入

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

样例输出

12
no solution

一种办法是枚举每个a,b,c,d,四个for,n^4,数据范围是1000,理论上必超时,但是看到网上的n^4交进去没有超时,可以知道这个题的数据很水..


思路:a+b+c=d; <——>a+b=d-c;我们先n^2扫一遍用map存下(a+b)的和,再n^2查看(d-c)是否再map里,注意一下枚举到和相等的时候每个a,b,c,d是不一样的。—这题原型是某喜欢养奶牛oj题,那道题的数据范围更大一点,并且有负数,map的查找时logn的,总的是n^2logn,可能卡常数.

用基于哈希表的unordered_map去查找是O(1)的,总的时间复杂度是O(n^2),可以过。

另外我🐎力太差,不知道if()里面的具体怎么写…所以贴出这个残次品


#include<iostream>
#include<vector>
#include<queue>
#include<cstring>
#include<algorithm>
#include<unordered_map> 
using namespace std;
const int maxn=1e5;
typedef long long LL;
LL a[maxn];
struct Node
{
	LL x;LL y;
};
vector<Node> res;
unordered_map< LL ,vector<Node> > mp;
int n;
LL solve()
{
	for(LL i=n;i>=1;i--)
	{
		for(LL j=1;j<i;j++)
		{
			LL sum=a[i]-a[j];
			///遍历vector..码不知道怎么写了..这个是错的 
				if(mp.find(sum)&&a[i]!=mp[sum][2].x&&a[j]!=mp[sum][2].y&&a[i]!=mp[sum][2].y&&a[j]!=mp[sum][2].x)
				{
					return a[i];
				}
		}
	}
	return 536870912;
}
int main(void)
{
	while(scanf("%d",&n)&&n)
	{
		mp.clear();memset(a,0,sizeof(a));
		for(LL i=1;i<=n;i++) cin>>a[i];
		sort(a+1,a+n+1);
		//枚举a 
		for(LL i=1;i<n;i++)
			for(LL j=i+1;j<=n;j++)
			{
				res.push_back({a[i],a[j]});
				mp.insert( {a[i]+a[j],res} );///怎么写噢...似乎可以..? 
			}	///mp[]里存a+b的值,下标为 a,b;
		LL ans=solve();
		if(ans==536870912) printf("no solution\n");
		else printf("%lld\n",ans);		 
	}
return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值