poj 2318 TOYS
题意:给定一个如上的长方形箱子,中间有n条线段,将其分为n+1个区域,给定m个玩具的坐标,统计每个区域中的玩具个数。
思路:这道题很水,只是要知道会使用叉乘来表示点在线的上面还是下面;
当a.Xmult(b,c) < 0时,表示在线的上面。之后就是二分的时候,不能直接使用mid来ans[mid]++;
因为只是确定点在这条线的两边,到底是哪一边,具体还要用tmp来判断;(模板题)
#include<iostream> #include<cstdio> #include<cstring> #include<string.h> #include<algorithm> #include<map> #include<queue> #include<vector> #include<cmath> #include<stdlib.h> #include<time.h> using namespace std; #define MS0(a) memset(a,0,sizeof(a)) const int MAXN = 5050; struct point{ int x,y; point(){} point(int _x,int _y){ x = _x; y = _y; } long long operator *(const point &b)const{// 叉乘 return (1LL*x*b.y - 1LL*y*b.x); } point operator -(const point &b)const{ return point(x - b.x,y - b.y); } long long dot(const point &b){ //点乘 return 1LL*x*b.x + 1LL*y*b.y; } double dist(const point &b){ return sqrt(1LL*(x-b.x)*(x-b.x)+1LL*(y-b.y)*(y-b.y)); } long long dist2(const point &b){ return 1LL*(x-b.x)*(x-b.x)+1LL*(y-b.y)*(y-b.y); } double len(){ return sqrt(1LL*x*x+1LL*y*y); } double point_to_segment(point b,point c)//点a到“线段” bc的距离a.point_to_segment(b,c); { point v[4]; v[1] = {c.x - b.x,c.y - b.y}; v[2] = {x - b.x,y - b.y}; v[3] = {x - c.x,y - c.y}; if(v[1].dot(v[2]) < 0) return v[2].len(); if(v[1].dot(v[3]) > 0) return v[3].len(); return fabs(1.*(v[1]*v[2])/v[1].len()); } long long Xmult(point b,point c){ // 当a->b与a->c顺时针转时,返回正; return (b-*this)*(c-*this); } void input(){ scanf("%d%d",&x,&y); } }p[MAXN]; struct Line{ point s,t; Line(){} Line(point _s,point _t){ s = _s,t =_t; } }line[MAXN]; int ans[MAXN]; int main() { int n,m,i,j,x1,y1,x2,y2,kase = 0,U,L; while(scanf("%d",&n),n){ MS0(ans); if(kase) puts(""); else kase++; scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2); for(i = 1;i <= n;i++){ scanf("%d%d",&U,&L); line[i] = Line(point(U,y1),point(L,y2)); } line[0] = Line(point(x1,y1),point(x1,y2)); int x,y; for(i = 0;i < m;i++){ scanf("%d%d",&x,&y); int l = 0, r = n,mid,tmp; while(l <= r){ mid = l + r >> 1; if( point(x,y).Xmult(line[mid].s,line[mid].t) < 0) r = mid-1; //在线的上边 else tmp = mid,l = mid+1; //线下的点所在的区域才是改line的标号; } ans[tmp]++; } for(i = 0;i <= n;i++){ printf("%d: %d\n",i,ans[i]); } } return 0; }