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