hdu4334

来源:互联网 发布:怎么看服务器端口 编辑:程序博客网 时间:2024/04/29 16:32

题意:有5个集合,从这5个集合中各取1个元素,使之和为0,如果存在输出Yes,否则输出No。

假设现在有两个有序序列,有两个指针,一个指向第一个序列的最大值,另一个指向第二个有序序列的最小值,将两个指针所指的值相加,如果小于固定值x,则第二个指针向值更大的方向移动,否则反之。

而这个题是5个集合,可以将1,2看作一组,将3,4看作一组,进行计算。具体的代码如下。

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>using namespace std;__int64 a[5][410],b[41000],c[41000];int n;int cmp(const void*a,const void*b){    if(*(__int64 *)a-*(__int64 *)b > 0)    return 1;    return -1;}int find(__int64 x){    int i=0,j=n*n-1,flag=0;        while(1)        {            if(i==n*n)    break;            if(j==-1)    break;            if(b[i]+c[j]>x)                j--;            if(b[i]+c[j]<x)                i++;            if(b[i]+c[j]==x)            {                flag=1;                break;            }        }    if(flag==1) return 1;    else    return 0;}int main(){    int t,i,j,k,k1,k2,flag;    scanf("%d",&t);    while(t--)    {        scanf("%d",&n);        memset(a,0,sizeof(a));        memset(b,0,sizeof(b));        memset(c,0,sizeof(c));        for(i=0;i<5;i++)        {            for(j=0;j<n;j++)                scanf("%I64d",&a[i][j]);        }        k1=0;        for(i=0;i<n;i++)        {            for(j=0;j<n;j++)            {                b[k1++]=a[0][i]+a[1][j];            }        }        qsort(b,n*n,sizeof(b[0]),cmp);        k2=0;        for(i=0;i<n;i++)            for(j=0;j<n;j++)                    c[k2++]=a[2][i]+a[3][j];        qsort(c,n*n,sizeof(c[0]),cmp);        flag=0;        for(i=0;i<n;i++)        {            if(find(-a[4][i])==1)            {                flag=1;                break;            }        }        if(flag==1) printf("Yes\n");        else    printf("No\n");    }    return 0;}


原创粉丝点击