hdu2141二分查找

http://acm.hdu.edu.cn/showproblem.php?pid=2141

本题关键在于处理上。

第一个处理是把原本A+B+C=x,变成D+C=x,就是用两个for循环把AB相加得到数组d[maxn*maxn];

第二个处理是把两个数组d[maxn*maxn],c[maxn]排序;

第三个处理是要么用二分查找,要么看看第二份代码用巧妙的查找来节省时间;

1.AC代码(用二分查找):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=500+10;
int a[maxn],b[maxn],c[maxn];
int d[maxn*maxn];
int l,n,m;
int x;
void searchn()
{
//    printf("^^^ %d ^^^",x);
    int flag;
    flag=0;
    for(int i=1; i<=m; i++)
    {
        int left=1,right=l*n;
        while(left<=right)
        {
            int mid=(left+right)/2;
//            printf("##%d##",d[mid]+c[i]);
            if(d[mid]==x-c[i])
            {
                flag=1;
                break;
            }
            else if(d[mid]<x-c[i])left=mid+1;
            else right=mid-1;
        }
    }
    if(flag)printf("YES\n");
    else printf("NO\n");
}
int main()
{
    int cas=1;
    while(~scanf("%d%d%d",&l,&n,&m))
    {
        for(int i=1; i<=l; i++)
            scanf("%d",&a[i]);
        for(int i=1; i<=n; i++)
            scanf("%d",&b[i]);
        for(int i=1; i<=m; i++)
            scanf("%d",&c[i]);
        int k=1;
        for(int i=1; i<=l; i++)
            for(int j=1; j<=n; j++)
                d[k++]=a[i]+b[j];
        sort(c+1,c+1+m);
        sort(d+1,d+1+l*n);
//        for(int i=1;i<=m;i++)
//            printf("%d *",c[i]);
//        cout<<endl;
//        for(int i=1;i<=l*n;i++)
//            printf("%d ^",d[i]);
        int s;
        cin>>s;
        printf("Case %d:\n",cas++);
        while(s--)
        {
            int flag=0;
            cin>>x;
            searchn();
        }
    }
    return 0;
}

 

 

2.AC代码(关键看查找):

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=500+10;
int a[maxn],b[maxn],c[maxn];
int d[maxn*maxn];
int main()
{
    int l,n,m;
    int cas=1;
    while(~scanf("%d%d%d",&l,&n,&m))
    {
        for(int i=1; i<=l; i++)
            scanf("%d",&a[i]);
        for(int i=1; i<=n; i++)
            scanf("%d",&b[i]);
        for(int i=1; i<=m; i++)
            scanf("%d",&c[i]);
        int k=1;
        for(int i=1; i<=l; i++)
            for(int j=1; j<=n; j++)
                d[k++]=a[i]+b[j];
        sort(c+1,c+1+m);
        sort(d+1,d+1+l*n);
        int s,x;
        cin>>s;
        printf("Case %d:\n",cas++);
        while(s--)
        {
            cin>>x;
            int i=1,j=m-1,flag=0;
            while(i<=l*n&&j>=1)//关键在此次的查找方式
            {//两个数组相加,一个从最大,一个从最小,相当于变相的从中间查找
                if(d[i]+c[j]==x)
                {
                    flag=1;
                    break;
                }
                else if(d[i]+c[j]>x)j--;
                else i++;
            }
            if(flag)printf("YES\n");
            else printf("NO\n");
        }
    }
    return 0;
}

 

posted @ 2013-08-16 20:33  拼搏今朝 努力奋进  阅读(127)  评论(0)    收藏  举报