POJ2318计算几何
http://acm.pku.edu.cn/JudgeOnline/problem?id=2318
题意:给你一块面积,给你n条线把这个面积分成n+1块,然后给m个点最后输出从第0块到第n块各有几个点;
关键:知道计算几何中一个基本定理,就是向量叉乘(向量叉积),给你一个点g(x,y)一条线(两个端点a(x,y),b(x,y)),判断点是在线的左边还是右边。向量(g-b)*向量(a-b)<0的话,点就在线的左边,>0就在右面。(判断的依据就是两个向量(g-b)*(a-b)<0的话,向量(g-b)就在向量(a-b)的逆时针方向,>0的话,向量(g-b)就在向量(a-b)的顺时针方向,都是以第二个向量为依据)
AC代码:
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> using namespace std; struct point { int x,y; }; point a[5010],b[5010];//a是线上面的点,b是下面的点 int c[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("%d%d%d%d",&g1.x,&g1.y,&g2.x,&g2.y); //面积边界 for(int i=1; i<=n; i++) { scanf("%d%d",&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; } n++; int mid,t; for(int i=1; i<=m; i++) { scanf("%d%d",&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]++; }//二分查找,每次从中间的一根线判断 for(int i=0; i<n; i++)//从第0块到原第n块 { printf("%d: %d\n",i,c[i]); } printf("\n"); } return 0; }

浙公网安备 33010602011771号