您的位置:首页 > 其它

poj2785题解

2016-05-21 17:12 357 查看
二分经典题,注意边界,否则wa到。。。。

由于4个for必定wa,所以分别对a和b,c和d求和,然后对其中一个进行排序,二分查找

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int ab[4010*4010],cd[4010*4010];
int N;
int mycmp(const void *a,const void *b)
{
return *((int *)a)-*((int *)b);
}
int main(int argc, char const *argv[])
{
int a[4010],b[4010],c[4010],d[4010],pos1,cnt,pos2,i,j,r,l,mid;
while(scanf("%d",&N)!=EOF)
{
cnt=0;
memset(ab,0,4010*4010*sizeof(int));
memset(cd,0,4010*4010*sizeof(int));
for(i=0;i<N;i++)
scanf("%d %d %d %d",a+i,b+i,c+i,d+i);
for(i=0;i<N;i++)
for(j=0;j<N;j++)
{
ab[i*N+j]=a[i]+b[j];
cd[i*N+j]=c[i]+d[j];
}
qsort(cd,N*N,sizeof(int),mycmp);
for(i=0;i<N*N;i++)
{
pos1=-1;pos2=-2;l=0;r=N*N;
if(-ab[i]==cd[N*N-1]) pos2=N*N-1;
else while(l<r)
{
mid=l+((r-l)>>1);
if(-ab[i]>cd[mid]||(-ab[i]==cd[mid]&&-ab[i]==cd[mid+1])) l=mid+1;
else if(-ab[i]<cd[mid]) r=mid;
else{
pos2=mid;break;
}
}
l=0;r=N*N;
if(-ab[i]==cd[0]) pos1=0;
else while(l<r)
{
mid=l+((r-l)>>1);
if(-ab[i]>cd[mid]) l=mid+1;
else if(-ab[i]<cd[mid]||(-ab[i]==cd[mid]&&-ab[i]==cd[mid-1])) r=mid;
else{
pos1=mid;break;
}
}
cnt+=pos2-pos1+1;
}
printf("%d\n",cnt );
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: