题意:一个矩形箱子,左上角与右下角的坐标给出,里面有n块板把箱子里的空间分隔成许多个分区,给出这些板在上边的x坐标、下边的x坐标,以及一堆玩具的坐标,求这些分区里的玩具数目。
分析:记玩具在点p0,某块板的上边点是p1,下边点是p2,p2p1(向量)×p2p0>0表示p0在p1p2的左面,<0表示在右面。接下来就是用二分法找出每个点所在的分区。
叉积+二分查找
#include<cstdio> #define vector point struct point { int x,y; point(int xx,int yy) { x = xx; y = yy; } point operator - (const point& s) { return point(x - s.x, y - s.y); } }; int cross_product(vector v1,vector v2) { return v1.x * v2.y - v1.y * v2.x; } int x1,y1,x2,y2; int n,m,board[5002][2],counter[5001]; int sort(int x,int y) { int left = 0, right = n + 1,mid; while(right - left > 1) { mid = (left + right)/2; vector v1 = vector(point(board[mid][0],y1) - point(board[mid][1],y2)), v2 = vector(point(x,y) - point(board[mid][1],y2)); /*printf("up = (%d,%d),down = (%d,%d), this.x = %d, this.y = %d\n",board[mid][0],y1,board[mid][1],y2,x,y); printf(" l = %d, r = %d, m = %d, (%d,%d)X(%d,%d) = %d\n",left,right,mid,v1.x,v1.y,v2.x,v2.y,cross_product(v1,v2));*/ if(cross_product(vector(point(board[mid][0],y1) - point(board[mid][1],y2)),vector(point(x,y) - point(board[mid][1],y2))) < 0)//在右邊 left = mid; else right = mid; } //printf("left = %d\n",left); return left; } int main() { bool flag = true; while(scanf("%d",&n) && n) { scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2); for(int i = 1;i <= n;i++) { scanf("%d%d",&board[i][0],&board[i][1]); counter[i] = 0; } counter[0] = 0; board[0][0] = board[0][1] = x1; board[n+1][0] = board[n+1][1] = x2; int x,y; for(int i = 0;i < m;i++) { scanf("%d%d",&x,&y); counter[sort(x,y)]++; } if(!flag) printf("\n"); else flag = false; for(int i = 0;i <= n;i++) printf("%d: %d\n",i,counter[i]); } return 0; }