zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    298. Binary Tree Longest Consecutive Sequence
    117. Populating Next Right Pointers in Each Node II
    116. Populating Next Right Pointers in Each Node
    163. Missing Ranges
    336. Palindrome Pairs
    727. Minimum Window Subsequence
    211. Add and Search Word
    年底购物狂欢,移动支付安全不容忽视
    成为程序员前需要做的10件事
    全球首推iOS应用防破解技术!
  • 原文地址:https://www.cnblogs.com/caiyishuai/p/13271172.html
Copyright © 2011-2022 走看看