7/21 A 解题报告

来源:互联网 发布:北京java晚班 编辑:程序博客网 时间:2024/06/15 20:20

7/21 A 解题报告

A题是说三个序列ABC,每个都有很多数,从每个序列中找出一个数相加等于给定的X。
这和紫书中的一个题类似,书上是4个集合找4个数相加为0。
基本方法就是把两个序列相加合并为一个和的集合,之后对这个集合排序并二分查找就有了。最终是nlogn的复杂度。如果二分的是另一个序列,则复杂度是n²logn,肯定不划算。
以下是代码(可直接AC):

#include <iostream>#include <algorithm>using namespace std;int tmp[250000];int comp(const void*a,const void*b){return *(int*)a-*(int*)b;}int main(){    int l,n,m,a[500],b[500],c[500],k,ca=0,p;    int x,y,z;    int low,high,mid;    bool flag,quit,con;    while(cin>>l>>n>>m)    {        x=y=z=0;        for(int i=0;i<l;i++)            cin>>a[i];        for(int i=0;i<m;i++)            cin>>b[i];        for(int i=0;i<n;i++)            cin>>c[i];        cin>>p;        x=0;        for(int j=0;j<l;j++)            {                for(int u=0;u<n;u++)                {                    tmp[x++]=a[j]+b[u];//合并AB                }            }            qsort(tmp,l*n,sizeof(int),comp);        cout<<"Case "<<++ca<<":"<<endl;        for(int i=0;i<p;i++)        {            quit=false;            flag=false;            con=true;            low=-1;high=m;                mid=(low+high)/2;            cin>>k;            for(int j=0;j<m&&!quit;j++)//对C集合每个元素            {                low=-1;high=l*n;//为了边界可以取                mid=(low+high)/2;            while(low<high-1)//二分            {                if(tmp[mid]+c[j]==k)                {                    quit=true;                    flag=true;                    cout<<"YES\n";                    break;                }else{                    if(tmp[mid]+c[j]>k)                    {                        high=mid;                        mid=(low+high)/2;                    }else{                        low=mid;                        mid=(low+high)/2;                    }                }            }            }            if(!flag)                cout<<"NO\n";        }    }    return 0;}
0 0
原创粉丝点击