【转】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;
}

  

posted @ 2015-08-15 17:16  _SunDaSheng  阅读(223)  评论(0编辑  收藏  举报