题目连接:
POJ 2318
题目大意:给一个长方体盒子,中间竖直插上若干隔板,将盒子分成了若干区域,现在往盒子里丢玩具,问最后各个区域内含有多少玩具。
这道题有两个思路:
一个是,将矩形区域分割成多个梯形区域,然后对每一个点进行判断,在哪一个区域中。(二分快一些)
一个是,将每个点与中间的隔板进行比较,如果在该隔板左边 则隔板左边的区域+1,在右边 则隔板右边的区域+1,输出的时候第一个区域不动,后面每个区域要减去前一个区域的点数再输出
题目大意:给一个长方体盒子,中间竖直插上若干隔板,将盒子分成了若干区域,现在往盒子里丢玩具,问最后各个区域内含有多少玩具。
这道题有两个思路:
一个是,将矩形区域分割成多个梯形区域,然后对每一个点进行判断,在哪一个区域中。(二分快一些)
一个是,将每个点与中间的隔板进行比较,如果在该隔板左边 则隔板左边的区域+1,在右边 则隔板右边的区域+1,输出的时候第一个区域不动,后面每个区域要减去前一个区域的点数再输出
// POJ 2318 TOYS -- 判断点在某个梯形内 叉积 + 二分
//
/*test data
1 1 0 10 60 0
3 1
40 10
5 6 0 10 60 0
3 1
4 3
6 8
10 10
15 30
1 5
2 1
2 8
5 5
40 10
7 9
4 10 0 10 100 0
20 20
40 40
60 60
80 80
5 10
15 10
25 10
35 10
45 10
55 10
65 10
75 10
85 10
95 10
0
==
0: 0
1: 1
0: 2
1: 1
2: 1
3: 1
4: 0
5: 1
0: 2
1: 2
2: 2
3: 2
4: 2
*/
#include <stdio.h>
#include <math.h>
#include <string.h>
const double Pzero = 0.000001;
const int MAXP = 5005;
struct POINT {
double x,y;
}toy[MAXP];
struct Square {
POINT a,b,c,d;
}s[MAXP];
int squ[5010]; // every square
double Abs(double a){
return (a>Pzero)?(a):(-a);
}
double XJ(POINT a,POINT b,POINT p){
// vector a->b (b.x-a.x, b.y-a.y)
// vector a->p (p.x-a.x, p.y-a.y)
// calc a->b X a->p
return ( (b.x-a.x)*(p.y-a.y) - (b.y-a.y)*(p.x-a.x) );
}
bool InSquare(POINT p,Square s){
// vector (s.b , s.a) point p
// vector (s.d , s.c) point p
// vector (s.c , s.a) point p
// vector (s.d , s.b) point p
//
if ((XJ(s.b, s.a, p) * XJ(s.d, s.c, p) < Pzero) && (XJ(s.c, s.a, p) * XJ(s.d, s.b, p) < Pzero))
return true;
return false;
}
int binaryserach(Square* regin, int begin, int end, POINT goal ){// 找到了返回数组中对应的下标,找不到返回-1
//查找的范围 查找的开始 查找的结束 目标
int mid = (begin + end) /2;
if ( InSquare(goal, regin[mid]) )
return mid;
if (begin >= end)
return -1;
if ( XJ(regin[mid].a, regin[mid].b, goal) < Pzero) // left
return binaryserach(regin,begin,mid-1,goal);
if ( XJ(regin[mid].c, regin[mid].d, goal) > Pzero) // right
return binaryserach(regin,mid+1,end,goal);
}
void calculation(int m,int ns){
for (int i=0;i<m;i++){
scanf("%lf%lf",&toy[i].x,&toy[i].y);
int j = binaryserach(s,0,ns,toy[i]);
if (j!=-1)
squ[j]++;
}
}
void init(int n,int m,POINT up,POINT low){
// from up to low
double tempa,tempb;
// left side
s[0].a.x = up.x;
s[0].a.y = up.y;
s[0].b.x = up.x;
s[0].b.y = low.y;
for (int i = 0; i < n; i++){
scanf("%lf%lf",&tempa,&tempb);
s[i].c.x = tempa;
s[i].c.y = up.y;
s[i].d.x = tempb;
s[i].d.y = low.y;
// next square
s[i+1].a.x = s[i].c.x;
s[i+1].a.y = s[i].c.y;
s[i+1].b.x = s[i].d.x;
s[i+1].b.y = s[i].d.y;
}
// right side
s[n].c.x = low.x;
s[n].c.y = up.y;
s[n].d.x = low.x;
s[n].d.y = low.y;
memset(squ, 0, sizeof(squ));
}
void PrintAns(int ns){
for (int i=0;i<ns;i++){
printf("%d: %d\n",i,squ[i]);
}
printf("\n");
}
int main()
{
// freopen("in.txt","r",stdin);
int n,m;
POINT up,low;
while(scanf("%d%d%lf%lf%lf%lf",&n,&m,&up.x,&up.y,&low.x,&low.y),n){
init(n,m,up,low);
calculation(m,n+1);
PrintAns(n+1);
}
return 0;
}