题目描述
最近,在课余时间流行一种游戏,游戏的规则如下:游戏开始时,每个人都从规定范围内的数中选取一个数(保证所选取的数各不相同),写在纸上,握在手中(以防让别的同学看见),然后同时打开,如果其中一个同学手中的数是其他任意两位同学手中的数之和,那么他就赢,如果满足条件的有多个,手中的数最大的那位同学赢。这是心理和智力的双重考验,所以参加的学生越来越多,但是,由于参与人数众多,要判断谁赢就成了问题,请聪明的你设计一个程序来解决这个问题!
输入
第1行为一个整数N(3≤N≤50000),表示参加游戏的总人数,第2行为N个数(范围在0~2^31之间),依次表示N个同学所选的数,第i个数表示第i位同学所选的数。
输出
只一行,为一个整数,表示哪位同学赢。如果没有任何一位同学赢,则输出“0”。
样例输入
5
2 5 7 3 13
样例输出
3
提示
100%的数据:N≤50000
根据题目的意思,我们想到把数据从小到大排序,然后从后向前对于每个数据都和它前面的数据进行比较,如果该数据与它前面的差值存在于总数据中,我们就可以结束遍历,并且答案就是这个数据所对应的人的位置
我们想到利用set中元素不重复的性质来实现遍历,但我们要注意两点:1、差值不能和被减数相等;2、被减数不能为0
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 typedef long long ll; 5 struct node 6 { 7 ll v,pos; 8 }mp[50005]; 9 bool cmp(node a,node b) 10 { 11 return a.v<b.v; 12 } 13 ll n; 14 int main() 15 { 16 ios::sync_with_stdio(false); 17 cin>>n; 18 set<ll>s; 19 for(ll i=0;i<n;i++) 20 { 21 cin>>mp[i].v; 22 mp[i].pos=i+1; 23 s.insert(mp[i].v); 24 } 25 sort(mp,mp+n,cmp); 26 bool flag=0; 27 for(ll i=n-1;i>=0;i--) 28 { 29 for(ll j=i-1;j>=0;j--) 30 { 31 if(mp[j].v==0) continue; 32 s.insert(mp[i].v-mp[j].v); 33 ll tmp=s.size(); 34 if(tmp==n&&mp[i].v!=2*mp[j].v) 35 { 36 cout<<mp[i].pos<<endl; 37 flag=1; 38 return 0; 39 } 40 else 41 { 42 s.erase(mp[i].v-mp[j].v); 43 } 44 } 45 } 46 if(!flag) 47 cout<<"0"<<endl; 48 return 0; 49 }