【转】ZOJ Problem Set - 1101 Gamblers:非暴力枚举
思路:
将所有数据从小到大排序,这样每次从序列的后面寻找答案ans,自然的确保了最大赌资性.
接下来就要枚举其他三个数了 进而 判断 此时的ans是否存在 其他三个数 和 等于ans.
而在三个数中至少有一个数在ans的前面 其他的两个数可能在ans的后面 因为存在负数.
这样就可以先枚举两个 赌注 进而第三个赌注可以由ans与 两个赌注 差 确定 从而二分搜索
如果存在第三个赌注 那么ans的赌注就是答案
如果枚举所有ans都找不到对应的第三个赌注则no solution
#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; const int Size=1000; int a[Size+1]; int n; int bsearch(int start, int val) { int L=start+1; int R=n-1; while(L<=R) { int mid=(L+R)/2; if( a[mid] == val ) return mid; else if(a[mid]<val) L=mid+1; else R=mid-1; } return 0; } int Enumer() { for(int i=n-1; i>0; i--) for(int j=0; j<i; j++) for(int k=j+1; k<n; k++){ int tmp=a[i]-a[j]-a[k]; int pos=bsearch(k, tmp); if(pos&&pos!=i) return i; } return 0; } int main() { while(cin>>n&&n) { for(int i=0; i<n; i++) cin>>a[i]; sort(a, a+n); if(Enumer()) cout<<a[Enumer()]<<endl; else cout<<"no solution"<<endl; } return 0; }