POJ2398计算几何
http://poj.org/problem?id=2398
题意:和POJ2318基本输入一样,但有一些改变。1.输入的线没按着从小到大的顺序,所以要先排序。2.输出要的是有1~m个点之间有多少个区间。例:有5条线,分成区域0,区域1,区域2,区域3,区域4,区域5.分别有2,1,3,5,4,0个点,所以输出就是1:1 2:1 3:1 4:1 5:1 ,再有就是看网上说用int会爆,所以改了一下范围。
AC代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; struct point { __int64 x,y; }; point a[5010],b[5010];//a是线上面的点,b是下面的点 int c[5010]; int d[5010]; int det(point a,point b,point g)//(g-b)*(a-b) { return (g.x-b.x)*(a.y-b.y)-(a.x-b.x)*(g.y-b.y); //x1*y2-x2*y1 } int main() { int n,m; point g,g1,g2; int minn,maxn; while(scanf("%d",&n)!=EOF&&n) { scanf("%d",&m); scanf("%I64d%I64d%I64d%I64d",&g1.x,&g1.y,&g2.x,&g2.y); //面积边界 for(int i=1; i<=n; i++) { scanf("%I64d%I64d",&a[i].x,&b[i].x); } a[n+1].x=g2.x; b[n+1].x=g2.x; a[0].x=g1.x; b[0].x=g1.x; for(int i=0; i<=n+1; i++) { a[i].y=g1.y; b[i].y=g2.y; c[i]=0; } for(int i=0;i<n-1;i++) { for(int j=1;j<n-i;j++) { if(a[j].x>a[j+1].x) { swap(a[j],a[j+1]); swap(b[j],b[j+1]); } } } //for(int i=1;i<=n;i++) //printf("%I64d %I64d ",a[i].x,b[i].x); n++; int mid,t; for(int i=1; i<=m; i++) { scanf("%I64d%I64d",&g.x,&g.y); minn=0; maxn=n; while(1) { mid=(minn+maxn)>>1; t=det(a[mid],b[mid],g); if(t<0)maxn=mid; else minn=mid; if(mid+1==maxn)break; } c[minn]++; //printf("%d *\n",minn); }//二分查找,每次从中间的一根线判断 printf("Box\n"); memset(d,0,sizeof(d)); for(int i=0;i<=n-1;i++) d[c[i]]++; for(int i=1;i<=m;i++) if(d[i]>0)printf("%d: %d\n",i,d[i]); } return 0; }

浙公网安备 33010602011771号