• POJ 2549 Sumsets(折半枚举+二分)


    Sumsets
    Time Limit: 1000MS   Memory Limit: 65536K
    Total Submissions: 11946   Accepted: 3299

    Description

    Given S, a set of integers, find the largest d such that a + b + c = d where a, b, c, and d are distinct elements of S.

    Input

    Several S, each consisting of a line containing an integer 1 <= n <= 1000 indicating the number of elements in S, followed by the elements of S, one per line. Each element of S is a distinct integer between -536870912 and +536870911 inclusive. The last line of input contains 0.

    Output

    For each S, a single line containing d, or a single line containing "no solution".

    Sample Input

    5
    2 
    3 
    5 
    7 
    12
    5
    2 
    16 
    64 
    256 
    1024
    0
    

    Sample Output

    12
    no solution
    

    Source

     

    题意

    给你一个公式a+b+c=d,让你在同一个集合(元素不同)内满足该条件时d的最大值,注意a b c d均不同。

    思路

    网上折半搜索的思路一般是将a+b+c=d拆分成 a+b=d-c

    优秀的代码

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<algorithm>
     5 using namespace std;
     6 const int inf = -600000000;
     7 int a[1001];
     8 int main()
     9 {
    10     int n;
    11     while (cin>>n&&n)
    12     {
    13         for (int i = 0; i < n; i++)
    14             cin >> a[i];
    15         sort(a, a + n);//从小到大
    16         n--;
    17         int ans = inf;
    18         for (int i = n; i >= 0; i--)
    19         {
    20             for (int j = n; j >= 0; j--)
    21             {
    22                 if (i == j)
    23                     continue;
    24                 int sum = a[i] - a[j];
    25                 for (int l = 0, r = j - 1; l<r;)//剩下用二分
    26                 {
    27                     if (a[l] + a[r] == sum)
    28                     {
    29                         if (l != i && r != i)
    30                         {
    31                             ans = a[i];
    32                             break;
    33                         }
    34                     }
    35                     if (a[l] + a[r]>sum)
    36                         r--;
    37                     else
    38                         l++;
    39                 }
    40                 if (ans != inf)
    41                     break;
    42             }
    43             if (ans != inf)
    44                 break;
    45         }
    46         if (ans == inf)
    47             printf("no solution
    ");
    48         else
    49             printf("%d
    ", ans);
    50     }
    51     return 0;
    52 }

    将a+b,c-d看成两个序列,然后二分查找。  注意不要忘记去重  

     1 #include<algorithm>  
     2 #include<cstdlib>  
     3 #include<cstring>  
     4 #include<string>  
     5 #include<stack>  
     6 #include<queue>  
     7 #include<iostream>  
     8 #include<cmath>  
     9 #include<map>  
    10 #include<list>  
    11 #include<stack>  
    12 typedef long long ll;  
    13 using namespace std;  
    14   
    15 int n;  
    16 int a[1005];  
    17   
    18 struct node{  
    19 int i,j;  
    20 int val;  
    21 }b[1005*1005];  
    22   
    23 bool cmp(node a,node b)  
    24 {  
    25     return a.val<b.val;  
    26 }  
    27   
    28 bool comp1(node a,int b)  
    29 {  
    30     return a.val<b;  // 找到第一个val>=b的结构体元素  
    31 }  
    32   
    33 bool comp2(node a,int b)  
    34 {  
    35     return a.val<=b; // 找到第一个val>b的结构体元素  
    36 }  
    37   
    38 int main()  
    39 {  
    40     while(scanf("%d",&n)==1&&n)  
    41     {  
    42         int i,j,k,m,t;  
    43         for(i=0;i<n;i++)  
    44             scanf("%d",a+i);  
    45         sort(a,a+n);  
    46   
    47         int len=0;  
    48         for(i=0;i<n;i++)  
    49         {  
    50             for(j=i+1;j<n;j++)  
    51             {  
    52                 if(a[i]!=a[j])  //这里直接判断一下 不同的话再存 以后就可以减少这部判断啦  
    53                 {  
    54                     b[len].i=i;  
    55                     b[len].j=j;  
    56                     b[len].val=a[i]+a[j]; //存储题意中的 a+b  
    57                     len++;  
    58                 }  
    59             }  
    60         }  
    61         sort(b,b+len,cmp);  //根据a+b的值从小到大排序  
    62   
    63         bool flag=false;  
    64         for(i=n-1;i>=0;i--) //之前已经从小到大对sort了 所以直接从最大的开始  
    65         {  
    66             int d=a[i];  //我们要找的d  
    67             for(j=0;j<i;j++)  
    68             {  
    69                 if(d!=a[j]) //d不能等于c  
    70                 {  
    71                     int cd=d-a[j];  //cd的值就相当于d-c  
    72                     node* p1=lower_bound(b,b+len,d-a[j],comp1);  
    73                     node* p2=lower_bound(b,b+len,d-a[j],comp2);//注意我写的两个函数comp, 而且都是作为lower_bound的参数  
    74                     if(p2-p1!=0)  //说明存在 a+b==d-c  
    75                     {  
    76                         while(p1!=p2) //还要判断一下a,b,c,d是否都不相同  
    77                         {  
    78                             if(a[p1->i]!=a[j]&&a[p1->i]!=a[i]&&a[p1->j]!=a[j]&&a[p1->j]!=a[i])  
    79                             {  
    80                                 flag=true;  //符合题意 直接跳出  
    81                                 break;  
    82                             }  
    83                             p1++;  
    84                         }  
    85                     }  
    86                 }  
    87                 if(flag)  //符合题意 直接跳出  
    88                     break;  
    89   
    90             }  
    91             if(flag)break;  //符合题意 直接跳出  
    92   
    93         }  
    94         if(flag)printf("%d
    ",a[i]); //符合题意 直接输出d 也就是a[i]  
    95         else printf("no solution
    ");  
    96   
    97     }  
    98   
    View Code
     1 #include<cstdio>  
     2 #include<algorithm>  
     3 using namespace std;  
     4 typedef long long ll;  
     5 const int maxn=1000+5;  
     6 ll t[maxn],d[maxn*maxn];  
     7 struct node  
     8 {  
     9     ll sum;  
    10     int use1,use2;  
    11 } c[maxn*maxn];  
    12 bool cmp(const node& a,const node& b)  
    13 {  
    14     return a.sum<b.sum;  
    15 }  
    16 int main()  
    17 {  
    18     int n;  
    19     while(~scanf("%d",&n),n)  
    20     {  
    21         int i,j,s=0;  
    22         for(i=0; i<n; i++)  
    23             scanf("%lld",&t[i]);  
    24         sort(t,t+n);  
    25         for(i=0; i<n; i++)  
    26             for(j=0; j<n; j++)  
    27                 if(i!=j)  
    28                 {  
    29                     c[s].sum=t[i]+t[j];  
    30                     c[s].use1=i;  
    31                     c[s++].use2=j;  
    32                 }  
    33         sort(c,c+s,cmp);  
    34         for(i=0; i<s; i++)  
    35             d[i]=c[i].sum;  
    36         ll ma=-1e17;  
    37         for(i=0; i<n; i++)  
    38         {  
    39             for(j=n-1; j>=0; j--)  
    40             {  
    41                 if(i!=j&&t[j]>ma)  
    42                 {  
    43                     ll u=-(t[i]-t[j]);  
    44                     int id1=lower_bound(d,d+s,u)-d;  
    45                     int id2=upper_bound(d,d+s,u)-d-1;  
    46                     for(int k=id1;k<id2;k++)  
    47                     {  
    48                         int a=c[k].use1,b=c[k].use2;  
    49                         if(a!=i&&a!=j&&b!=i&&b!=j)  
    50                         {  
    51                             ma=t[j];break;  
    52                         }  
    53                     }  
    54                 }  
    55             }  
    56         }  
    57         if(ma!=-1e17)printf("%lld
    ",ma);  
    58         else printf("no solution
    ");  
    59     }  
    60     return 0;  
    61 } 
    View Code
  • 相关阅读:
    ZOJ 3656Bit Magic解题报告——2sat问题建图总结
    gcc和g++的区别
    07车展,流水账。。
    放开思维啊~~~
    SC2和其他
    幻觉~
    去横店咯~
    ETS。。New G。。
    老子毕业鸟。。。
    gcc常用参数和环境变量小结
  • 原文地址:https://www.cnblogs.com/caiyishuai/p/8465665.html
Copyright © 2020-2023  润新知