uva10125Sumsets

来源:互联网 发布:python linux 编辑:程序博客网 时间:2024/05/15 04:33

看似简单的题,其实要求考虑的非常严密

首先如果枚举a,b,c再判断d的话肯定超时,即使用hash存d也一样,解决办法是根据a+b=d-c先把所有d-c的值用hash存起来,再枚举所有a+b,这样枚举量就减小到1000*999了。

然后,每组a,b和每组c,d都必须考虑,不能先排序再枚举1000*999/2,因为d不一定是四个数字中最小的。

最后,当a+b==d-c时,还必须判断他们互不相等。

#include<cstdio>#include<cstring>#include<algorithm>#define HASHSIZE 10000003#define MAX 5000000using namespace std;int s[1000],head1[HASHSIZE],next1[MAX],s1[MAX][2];int hash(int value){    if(value<0)        value=-value;    return (value)%HASHSIZE;}void insert(int i,int j,int t){    int sum=s[j]-s[i];    int hashvalue=hash(sum);    int u=head1[hashvalue];    while(u!=-1)    {        u=next1[u];    }    next1[t]=head1[hashvalue];    head1[hashvalue]=t;}int find(int i,int j){    int all=s[i]+s[j];    int hashvalue=hash(all);    int u=head1[hashvalue];    while(u!=-1)    {        if(s[s1[u][1]]-s[s1[u][0]]==all&&s[s1[u][1]]!=s[i]&&s[s1[u][1]]!=s[j]&&s[s1[u][0]]!=s[i]&&s[s1[u][0]]!=s[j])            return s[s1[u][1]];        u=next1[u];    }    return -1000000000;}int main(){    int n,i,j,t,flag,help,large;    while(scanf("%d",&n)&&n)    {        flag=0;        large=-1000000000;        memset(head1,-1,HASHSIZE*4);        for(i=0;i<n;i++)        {            scanf("%d",&s[i]);        }        //sort(s,s+n);        t=0;        for(i=0;i<n;i++)        {            for(j=0;j<n;j++)            {                if(i==j)                    continue;                s1[t][0]=i;                s1[t][1]=j;                insert(i,j,t);                t++;            }        }        for(i=0;i<n;i++)        {            for(j=0;j<n;j++)            {                if(i==j)                    continue;                if((help=find(i,j))!=-1000000000)                {                    flag=1;                    if(help>large)                        large=help;                }            }        }        if(flag==0)            printf("no solution\n");        else            printf("%d\n",large);    }    return 0;}


0 0