题目链接:http://poj.org/problem?id=2398
题解:叉积+二分
此题与POJ2318类似 不过板子需要排序
#include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #include<iostream> using namespace std; struct Point { double x, y; Point(double x = 0, double y = 0) : x(x), y(y) {} }; typedef Point Vector; //Vector 为 Point的别名 //向量+向量=向量 点+向量=点 Vector operator + (Vector A, Vector B) {return Vector(A.x+B.x, A.y+B.y);} //点-点=向量 Vector operator - (Point A, Point B) {return Vector(A.x-B.x, A.y-B.y);} //向量*数=向量 Vector operator * (Vector A, double p) {return Vector(A.x*p, A.y*p);} //向量/数=向量 Vector operator / (Vector A, double p) {return Vector(A.x/p, A.y/p);} bool operator < (const Point & a, const Point & b) { return a.x < b.x || (a.x == b.x && a.y < b.y); } const double eps = 1e-10; int dcmp(double x) { if(fabs(x) < eps) return 0; else return x < 0 ? -1 : 1; } //叉积:两向量v和w的叉积等于v和w组成的三角形的有向面积的两倍 XaYb - XbYa double Cross(Vector A, Vector B) { return A.x*B.y - A.y*B.x; } #define MAXN 1111 struct Ban { Point up, low; }ban[MAXN]; bool cmp(Ban a, Ban b) { if(a.up.x == b.up.x) return a.low < b.low; return a.up < b.up; } int main () { int n, m, x1, y1, x2, y2; while(scanf("%d", &n), n) { scanf("%d %d %d %d %d", &m, &x1, &y1 , &x2, &y2); ban[0].up.x = x1, ban[0].up.y = y1; ban[0].low.x = x1, ban[0].low.y = y2; ban[n+1].up.x = x2, ban[n+1].up.y = y1; ban[n+1].low.x = x2, ban[n+1].low.y = y2; for(int i = 1; i <= n; i++) { scanf("%lf %lf", &ban[i].up.x, &ban[i].low.x); ban[i].up.y = y1; ban[i].low.y = y2; } sort(ban+1, ban+n+1, cmp); memset(ans, 0, sizeof(ans)); for(int i = 1; i <= m; i++) { Point tmp; scanf("%lf %lf", &tmp.x, &tmp.y); //二分 int l = 0, r = n+1; while(l < r) { int M = l + (r-l)/2; if(dcmp(Cross(ban[M].up-ban[M].low, tmp-ban[M].low))>0) r = M; else l = M+1; } ans[l-1]++; } int num[MAXN]; memset(num, 0, sizeof(num)); for(int i = 0; i <= n; i++) num[ans[i]]++; //sort(num+1, num+m+1, cmpp); printf("Box\n"); for(int i = 1; i <= m; i++) { if(num[i] != 0) printf("%d: %d\n", i, num[i]); } } return 0; }