前言
这道题原本老师说是哈希的练习题,结果发现哈希的代码量忒大,然后就用二分了。
正题
有n个赌徒,如果一个赌徒的钱数是其中三个的和那么这个赌徒是赢家,输出最多钱的赢家。
输入输出(建议无视)
Input
输入一个整数n (1<=n<=1000)表示有n个赌徒。
接下去n行各自输入一个整数 x (-536870912
Output
输出每组测试数据的结果。如果没有胜者则输出”no solution”.
Sample Input
5
2
3
5
7
12
5
2
16
64
256
1024
0
Output for Sample Input
12
no solution
解题思路
将4重循环分成两段,变为两个二重循环。第一个二重循环把所有值记录下来,然后第二个二重循环中用二分查找合适的答案。注意由于可能有多组答案相等的数据,由于需要其中去重的性质,所有哈希很麻烦。
代码
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,a[1001],S,len,wz;
struct hehe{int first,last,c;
};//结构体
hehe sum[1000006];
bool f;
int find(int x)//二分查找
{int mid,l=1,r=len;while (l<=r){mid=(l+r)/2;if (sum[mid].c==x) {return mid;}if (sum[mid].c<x) l=mid+1;else r=mid-1;}return -1;
}
bool cmp(hehe x,hehe y)
{return x.c<y.c;
}//快排用
int main()
{while (true){len=0;f=false;scanf("%d",&n);if (n==0) break;for (int i=1;i<=n;i++){scanf("%d",&a[i]);}sort(a+1,a+1+n);//排序,后面有用for (int i=1;i<n;i++){for (int j=i+1;j<=n;j++){sum[++len].c=a[i]+a[j];/.记录sum[len].first=i;//记录去重sum[len].last=j;}}sort(sum+1,sum+1+len,cmp);for (int i=n;i>=1;i--){for (int j=1;j<=n;j++){if (i==j) continue;//去重wz=find(a[i]-a[j]);//查找if (wz==-1) continue;while (wz<=len && sum[wz].c==a[i]-a[j] && !f)//前面可能有多组相同答案{if (sum[wz].first!=i && sum[wz].last!=j && sum[wz].first!=j && sum[wz].last!=i)//去重{S=a[i];f=true;break;//由于前面排了序所有一旦找到就是最大的}wz++;}if (f) break;}if (f) break;}if (f) printf("%d\n",S);else printf("no solution\n");//输出}
}