【解题报告】 POJ 2318 TOYS -- 判断点在某个梯形内 叉积 + 二分

来源:互联网 发布:淘宝客是啥 编辑:程序博客网 时间:2024/05/22 03:13
题目连接: POJ 2318
题目大意:给一个长方体盒子,中间竖直插上若干隔板,将盒子分成了若干区域,现在往盒子里丢玩具,问最后各个区域内含有多少玩具。
这道题有两个思路:
             一个是,将矩形区域分割成多个梯形区域,然后对每一个点进行判断,在哪一个区域中。(二分快一些)
             一个是,将每个点与中间的隔板进行比较,如果在该隔板左边 则隔板左边的区域+1,在右边 则隔板右边的区域+1,输出的时候第一个区域不动,后面每个区域要减去前一个区域的点数再输出
// POJ 2318 TOYS -- 判断点在某个梯形内   叉积 + 二分///*test data1 1 0 10 60 03 140 105 6 0 10 60 03 14 36 810 1015 301 52 12 85 540 107 94 10 0 10 100 020 2040 4060 6080 80 5 1015 1025 1035 1045 1055 1065 1075 1085 1095 100==0: 01: 10: 21: 12: 13: 14: 05: 10: 21: 22: 23: 24: 2*/#include <stdio.h>#include <math.h>#include <string.h>const double Pzero = 0.000001;const int MAXP = 5005;struct POINT {double x,y;}toy[MAXP];struct Square {POINT a,b,c,d;}s[MAXP];int squ[5010]; // every squaredouble Abs(double a){return (a>Pzero)?(a):(-a);}double XJ(POINT a,POINT b,POINT p){// vector a->b (b.x-a.x, b.y-a.y)// vector a->p (p.x-a.x, p.y-a.y)// calc a->b X a->preturn ( (b.x-a.x)*(p.y-a.y) - (b.y-a.y)*(p.x-a.x) );}bool InSquare(POINT p,Square s){// vector (s.b , s.a) point p// vector (s.d , s.c) point p// vector (s.c , s.a) point p// vector (s.d , s.b) point p// if ((XJ(s.b, s.a, p) * XJ(s.d, s.c, p) < Pzero) && (XJ(s.c, s.a, p) * XJ(s.d, s.b, p) < Pzero))return true;return false;}int binaryserach(Square* regin,int begin, int end, POINT goal){// 找到了返回数组中对应的下标,找不到返回-1//查找的范围 查找的开始  查找的结束 目标int mid = (begin + end) /2;if ( InSquare(goal, regin[mid]) )return mid;if (begin >= end) return -1;if ( XJ(regin[mid].a, regin[mid].b, goal) < Pzero) // leftreturn binaryserach(regin,begin,mid-1,goal);if ( XJ(regin[mid].c, regin[mid].d, goal) > Pzero) // rightreturn binaryserach(regin,mid+1,end,goal);}void calculation(int m,int ns){for (int i=0;i<m;i++){scanf("%lf%lf",&toy[i].x,&toy[i].y);int j = binaryserach(s,0,ns,toy[i]);if (j!=-1)squ[j]++;}}void init(int n,int m,POINT up,POINT low){// from up to lowdouble tempa,tempb;// left sides[0].a.x = up.x;s[0].a.y = up.y;s[0].b.x = up.x;s[0].b.y = low.y;for (int i = 0; i < n; i++){scanf("%lf%lf",&tempa,&tempb);s[i].c.x = tempa;s[i].c.y = up.y;s[i].d.x = tempb;s[i].d.y = low.y; // next squares[i+1].a.x = s[i].c.x;s[i+1].a.y = s[i].c.y;s[i+1].b.x = s[i].d.x;s[i+1].b.y = s[i].d.y;}// right sides[n].c.x = low.x;s[n].c.y = up.y;s[n].d.x = low.x;s[n].d.y = low.y; memset(squ, 0, sizeof(squ));}void PrintAns(int ns){for (int i=0;i<ns;i++){printf("%d: %d\n",i,squ[i]);}printf("\n");}int main(){//freopen("in.txt","r",stdin);int n,m;POINT up,low;while(scanf("%d%d%lf%lf%lf%lf",&n,&m,&up.x,&up.y,&low.x,&low.y),n){init(n,m,up,low);calculation(m,n+1);PrintAns(n+1);}return 0;}