您的位置:首页 > 产品设计 > UI/UE

POJ2785-4 Values whose Sum is 0

2011-08-03 20:42 239 查看
  纯暴力是n^4果断超时。本题得解法可以采用二分搜索。时间复杂度n^2(logn)的样子,空间复杂度n^2。虽然还是非常巨大,但是本题可以险过,时间大概5s。

  采用两个数组a[],b[]分别记录前两列所有可能的和与后两列所有可能的和,N^2级。然后对两个数组排序,便于统计每个值出现的次数,每个数组变为了两个数组,一个保存所有可能的值,只保存一个,仍为a[],另设一个数组c[],c[i]==(a[i]的个数)。b,d类似。然后对a中每一个数a[i]在b内二分搜索a[i]*(-1),如果存在b[j]==a[i]*(-1),返回d[j],没有就返回0。如果返回值不为0则总数加上d[j]*c[i]。

#include<iostream> #include<algorithm> #include<string.h> #include<cstring> #include<cmath> #include<cstdio> usingnamespacestd; /* *预处理+二分搜索 */ constintN=16000005; inta ,b ,c ,d ; intp[4005][4]; //二分搜索一个值在b数组中的个数 intsearch(intn,intx){ // intl=0,r=n-1,mid; while(l<=r){ mid=(l+r)/2; if(b[mid]==x) returnd[mid]; elseif(b[mid]<x)l=mid+1; elser=mid-1; } return0; } intmain(){ intn,k; while(scanf("%d",&n)!=EOF){ for(inti=0;i<n;i++) for(intj=0;j<4;j++) scanf("%d",&p[i][j]); //a保存前两列可能的和,b保存后两列可能的和 k=0; for(inti=0;i<n;i++) for(intj=0;j<n;j++) a[k++]=p[i][0]+p[j][1]; k=0; for(inti=0;i<n;i++) for(intj=0;j<n;j++) b[k++]=p[i][2]+p[j][3]; sort(a,a+k);//排序 sort(b,b+k);//【排序 intt=0,h=0; c[0]=d[0]=1; //对数组a预处理,如果存在重复则记录这个值重复的次数 //而且重复的值只保留一个 for(inti=1;i<k;i++){ if(a[i]==a[t]) c[t]++; else{ t++; a[t]=a[i]; c[t]=1; } } //b类似 for(inti=1;i<k;i++){ if(b[i]==b[h]) d[h]++; else{ h++; b[h]=b[i]; d[h]=1; } } __int64sum=0; for(inti=0;i<=t;i++){ sum+=search(h+1,a[i]*(-1))*c[i]; } printf("%I64d\n",sum); } return0; }

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: