题目链接:http://poj.org/problem?id=2398
————————————————————————————————————————————
题目大意:给n条线划分矩形,分成了n+1个格子,再给m个点,判断这m点在哪个格子里。输出含有相同数目点的格子的个数
————————————————————————————————————————————
题目思路:要求的输出比较奇怪。
二分法,并通过叉积判断点的位置。顺时针,叉积小于0;逆时针,叉积大于0. 题目中说不需考虑在划分线的情况。
最后,格子的左边界来记录该格子中点的数量,自然最后一条线就没用了。
————————————————————————————————————————————
题目小结:本题较为基本,第一次写c++,重载时遇到了一些问题,好在下学期就该学c++了。本题中定义的结构体可以作为计算几何的基本模板。
ok,开始计算几何之旅!先休息下眼睛。
————————————————————————————————————————————
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef float T;
struct Pt
{
T x;
T y;
Pt(){}
Pt(T px,T py)
{
x = px;
y = py;
}
Pt &operator +(const Pt &p) const
{
Pt c;
c.x = x + p.x;
c.y = y + p.y;
return c;
}
Pt &operator -(const Pt &p) const
{
Pt c;
c.x = x - p.x;
c.y = y - p.y;
return c;
}
};
struct Line
{
Pt a;
Pt b;
int cont;
Line(){}
Line (Pt p1,Pt p2)
{
a = p1;
b = p2;
}
}line[1010];
T dpr(Pt a,Pt b,Pt c) //点积
{
return (b.x-a.x)*(c.x-a.x)+(b.y-a.y)*(c.y-a.y);
}
T cpr(Pt a,Pt b,Pt c) //ab * ac
{
return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
bool cmp(Line l1,Line l2)
{
return l1.a.x < l2.a.x;
}
int main()
{
int n = 0,m = 0,i = 0;
T x1 = 0,y1 = 0,x2 = 0,y2 = 0,u = 0,l = 0;
int con[1010];
scanf("%d",&n);
while(n!=0)
{
scanf("%d%f%f%f%f",&m,&x1,&y1,&x2,&y2);
line[0] = Line(Pt(x1,y1),Pt(x1,y2));
line[0].cont = 0;
for(i = 1;i<=n;i++)
{
scanf("%f%f",&u,&l);
line[i] = Line(Pt(u,y1),Pt(l,y2));
line[i].cont = 0;
}
line[i] = Line(Pt(x2,y1),Pt(x2,y2));
sort(line,line+1+n,cmp);
for(i = 0;i<m;i++)
{
int left = 0,right = n+1,m = (left+right)/2;
scanf("%f%f",&u,&l);
while(!(cpr(Pt(u,l),line[m].a,line[m].b)>0 && cpr(Pt(u,l),line[m+1].a,line[m+1].b)<0))
{
if(cpr(Pt(u,l),line[m].a,line[m].b)>0) left = m+1;
if(cpr(Pt(u,l),line[m].a,line[m].b)<0) right = m-1;
m = (left+right)/2;
}
line[m].cont ++;
}
printf("Box\n");
for(i = 0;i<=m;i++) con[i] = 0;
for(i = 0;i<=n;i++)
con[line[i].cont] ++;
for(i = 1;i<=m;i++)
{
if(con[i]>=1)
printf("%d: %d\n",i,con[i]);
}
scanf("%d",&n);
}
return 0;
}