zoukankan      html  css  js  c++  java
  • Can you find it?(二分 二分+STL set map)

    Can you find it?

    Time Limit : 10000/3000ms (Java/Other)   Memory Limit : 32768/10000K (Java/Other)
    Total Submission(s) : 25   Accepted Submission(s) : 7
    Problem Description
    Give you three sequences of numbers A, B, C, then we give you a number X. Now you need to calculate if you can find the three numbers Ai, Bj, Ck, which satisfy the formula Ai+Bj+Ck = X.
     
    Input
    There are many cases. Every data case is described as followed: In the first line there are three integers L, N, M, in the second line there are L integers represent the sequence A, in the third line there are N integers represent the sequences B, in the forth line there are M integers represent the sequence C. In the fifth line there is an integer S represents there are S integers X to be calculated. 1<=L, N, M<=500, 1<=S<=1000. all the integers are 32-integers.
     
    Output
    For each case, firstly you have to print the case number as the form "Case d:", then for the S queries, you calculate if the formula can be satisfied or not. If satisfied, you print "YES", otherwise print "NO".
     
    Sample Input
    3 3 3 1 2 3 1 2 3 1 2 3 3 1 4 10
     
    Sample Output
    Case 1: NO YES NO
    题意:分别有a,b,c三个数组,给出一个数,看这个数能不能再a,b,c,里面分别找出一个数求和得到
    题解:先把两个数组加起来,另外一个数组用二分;
    代码:
     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 using namespace std;
     5 __int64 D[1000010],A[510],B[510],C[510],L,N,M;//D数组要开大;;; 
     6 int erfen(__int64 *a,__int64 c,__int64 d){ 
     7     int l,r,mid;
     8     l=0;r=L*N-1;//////// 
     9     while(l<=r){
    10         mid=(l+r)/2;
    11         if(a[mid]+c<d)l=mid+1;
    12         else r=mid-1;
    13         if(a[mid]+c==d)return 1;//这点弄错了,交了几十遍。。。。。 
    14     }
    15     return 0;
    16 }
    17 int search(__int64 *a,__int64 *b,__int64 c){
    18     for(int i=0;a[i];i++){
    19         if(erfen(b,a[i],c))return 1;
    20     }
    21     return 0;
    22 }
    23 void merge(__int64 *a,__int64 *b,__int64 *c){
    24     int t=0;
    25     for(int i=0;a[i];i++){
    26         for(int j=0;b[j];j++){
    27             c[t++]=a[i]+b[j];
    28         }
    29     }
    30 }
    31 int main(){
    32     __int64 S,flot=0,X;
    33     while(~scanf("%I64d%I64d%I64d",&L,&N,&M)){flot++;
    34         for(int i=0;i<L;++i)scanf("%I64d",&A[i]);
    35         for(int i=0;i<N;++i)scanf("%I64d",&B[i]);
    36         for(int i=0;i<M;++i)scanf("%I64d",&C[i]);
    37         merge(A,B,D);
    38         sort(D,D+L*N);//这里也错了好多次,是相乘 
    39             //for(int i=0;i<L+N;i++)printf("%d ",D[i]);
    40         scanf("%I64d",&S);
    41         printf("Case %I64d:
    ",flot);
    42         while(S--){
    43             scanf("%I64d",&X);
    44             if(search(C,D,X))puts("YES");
    45             else puts("NO");
    46         }
    47     }
    48     return 0;
    49 }

     stl:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<algorithm>
     4 using namespace std;
     5 __int64 D[1000010],A[510],B[510],C[510],L,N,M;//D数组要开大;;; 
     6 /*int erfen(__int64 *a,__int64 c,__int64 d){ 
     7     int l,r,mid;
     8     l=0;r=L*N-1;//////// 
     9     while(l<=r){
    10         mid=(l+r)/2;
    11         if(a[mid]+c<d)l=mid+1;
    12         else r=mid-1;
    13         if(a[mid]+c==d)return 1;//这点弄错了,交了几十遍。。。。。 
    14     }
    15     return 0;
    16 }*/
    17 int search(__int64 *a,__int64 *b,__int64 c){
    18     for(int i=0;a[i];i++){
    19         if(*lower_bound(b,b+L*N,c-a[i])==c-a[i])return 1;/*lower_bound返回的是b数组中第一个大于等于c-a[i]元素的的地址 
    20         upper(begin,end,index)找到大于某值的第一次出现; 
    21         */
    22     }
    23     return 0;
    24 }
    25 void merge(__int64 *a,__int64 *b,__int64 *c){
    26     int t=0;
    27     for(int i=0;a[i];i++){
    28         for(int j=0;b[j];j++){
    29             c[t++]=a[i]+b[j];
    30         }
    31     }
    32 }
    33 int main(){
    34     __int64 S,flot=0,X;
    35     while(~scanf("%I64d%I64d%I64d",&L,&N,&M)){flot++;
    36         for(int i=0;i<L;++i)scanf("%I64d",&A[i]);
    37         for(int i=0;i<N;++i)scanf("%I64d",&B[i]);
    38         for(int i=0;i<M;++i)scanf("%I64d",&C[i]);
    39         merge(A,B,D);
    40         sort(D,D+L*N);//这里也错了好多次,是相乘 
    41             //for(int i=0;i<L+N;i++)printf("%d ",D[i]);
    42         scanf("%I64d",&S);
    43         printf("Case %I64d:
    ",flot);
    44         while(S--){
    45             scanf("%I64d",&X);
    46             if(search(C,D,X))puts("YES");
    47             else puts("NO");
    48         }
    49     }
    50     return 0;
    51 }

     map和set做全都MLE了,无奈了,别人的都对的;

    set代码:

     1 #include<stdio.h>
     2 #include<set>
     3 using namespace std;
     4 const int MAXN=505;
     5 int A[MAXN],B[MAXN],C[MAXN];
     6 int main(){
     7     int L,N,M,S,X,flot=0,ok;
     8     while(~scanf("%d%d%d",&L,&N,&M)){set<int>num;
     9         for(int i=0;i<L;++i)scanf("%d",&A[i]);
    10         for(int i=0;i<N;++i)scanf("%d",&B[i]);
    11         for(int i=0;i<M;++i)scanf("%d",&C[i]);
    12         for(int i=0;i<L;i++)for(int j=0;j<N;j++)num.insert(A[i]+B[j]);
    13         scanf("%d",&S);
    14         printf("Case %d:
    ",flot++);
    15         while(S--){ok=0;
    16             scanf("%d",&X);for(int i=0;C[i];i++){
    17         if(num.find(X-C[i])!=num.end()){ok=1;break;}
    18         }
    19             if(ok)puts("YES");
    20             else puts("NO");
    21         }
    22     }
    23     return 0;
    24 } 

    map代码:

     1 #include<stdio.h>
     2 #include<map>
     3 using namespace std;
     4 const int MAXN=505;
     5 int A[MAXN],B[MAXN],C[MAXN];
     6 int main(){
     7     int L,N,M,S,X,flot=0,ok;
     8     while(~scanf("%d%d%d",&L,&N,&M)){map<int,bool>num;
     9         for(int i=0;i<L;++i)scanf("%d",&A[i]);
    10         for(int i=0;i<N;++i)scanf("%d",&B[i]);
    11         for(int i=0;i<M;++i)scanf("%d",&C[i]);
    12         for(int i=0;i<L;i++)for(int j=0;j<N;j++)num[A[i]+B[j]]=1;
    13         scanf("%d",&S);
    14         printf("Case %d:
    ",flot++);
    15         while(S--){ok=0;
    16             scanf("%d",&X);for(int i=0;C[i];i++){
    17         if(num.count(X-C[i])){ok=1;break;}
    18         }
    19             if(ok)puts("YES");
    20             else puts("NO");
    21         }
    22     }
    23     return 0;
    24 } 
  • 相关阅读:
    AC日记——Little Elephant and Numbers codeforces 221b
    AC日记——Little Elephant and Function codeforces 221a
    AC日记——Mice and Holes codeforces 797f
    AC日记——Sliding Window poj 2823
    Poj 2976 Dropping tests(01分数规划 牛顿迭代)
    Bzoj 1968: [Ahoi2005]COMMON 约数研究
    洛谷 P2424 约数和
    Hdu Can you find it?(二分答案)
    SPOJ GSS1
    Bzoj 2243: [SDOI2011]染色(树链剖分+线段树)
  • 原文地址:https://www.cnblogs.com/handsomecui/p/4689111.html
Copyright © 2011-2022 走看看