题意
给出一个矩形,和矩形内的一些线段,将矩形划分为若干box,再在矩形内放置若干点,问box内点的数量有有哪些,分别有几个box内有这么多的点。
思路
通过叉积来判断点和线的关心,设点为 p0 ,线段为 p1p2 ,则若 det(p0p1,p0p2) 小于0,则点在线的左侧,大于0 则点在直线的右侧,以此为依据二分(要先将线段排序),求得点所在盒子的编号。
代码
#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
const int maxn = 1e3+5;
// -------------------- 通用基本常数 --------------------
const double eps = 1e-8;
const double pi = acos(-1.0);
// -------------------- 二维点(向量)类 --------------------
struct Point {
int x, y;
Point() {}
Point(int x, int y): x(x), y(y) {}
// 输入一个点
void input() {
scanf("%lf%lf", &x, &y);
}
friend Point operator + (const Point& a, const Point& b) {
return Point(a.x + b.x, a.y + b.y);
}
friend Point operator - (const Point& a, const Point& b) {
return Point(a.x - b.x, a.y - b.y);
}
friend Point operator * (const Point& a, const double& b) {
return Point(a.x * b, a.y * b);
}
friend Point operator * (const double& a, const Point& b) {
return Point(a * b.x, a * b.y);
}
friend Point operator / (const Point& a, const double& b) {
return Point(a.x / b, a.y / b);
}
};
// -------------------- 向量与向量运算 --------------------
// 计算两个向量的叉积
double det(const Point& a, const Point& b) {
return a.x * b.y - a.y * b.x;
}
// 计算两个向量的点积
double dot(const Point &a, const Point& b) {
return a.x * b.x + a.y * b.y;
}
// -------------------- 线段(直线)类 --------------------
struct Line {
Point a, b;
Line() {}
Line(Point x, Point y): a(x), b(y) {}
};
bool cmp(Line &a, Line &b){
return a.a.x < b.a.x;
}
Line line[maxn];
Point toy;
int box[maxn];
int ans[maxn];
int main (){
Point LT,RL;
int n,m;
while(~scanf("%d",&n) && n){
scanf("%d %d %d %d %d",&m,<.x,<.y,&RL.x,&RL.y);
for(int i = 0 ; i < n ; i ++){
int Ui,Li;
scanf("%d %d", &Ui,&Li);
line[i] = Line(Point(Ui,LT.y),Point(Li,RL.y));
}
line[n] = Line(Point(RL.x,LT.y),RL);
sort(line,line + n+1, cmp);
memset(box,0,sizeof box);
memset(ans,0,sizeof ans);
for(int i = 0 ; i < m ; i ++){
int x,y;
scanf("%d %d", &x,&y);
toy = Point(x,y);
int l = 0 , r = n;
int loc = 0;
while(l <= r){
int mid = (l+r) >> 1;
if (det(line[mid].a - toy,line[mid].b - toy) < 0){
loc = mid;
r = mid -1;
}
else {
loc = mid +1;
l = mid + 1;
}
}
box[loc] ++;
}
puts("Box");
for(int i = 0 ; i <= n ; i ++)
ans[box[i]] ++;
for(int i = 1 ; i <= n ; i ++)
if(ans[i])
printf("%d: %d\n",i,ans[i]);
}
return 0;
}