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