poj 2318 TOYS(计算几何)

TOYS
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 13159   Accepted: 6357

Description

Calculate the number of toys that land in each bin of a partitioned toy box. 
Mom and dad have a problem - their child John never puts his toys away when he is finished playing with them. They gave John a rectangular box to put his toys in, but John is rebellious and obeys his parents by simply throwing his toys into the box. All the toys get mixed up, and it is impossible for John to find his favorite toys. 

John's parents came up with the following idea. They put cardboard partitions into the box. Even if John keeps throwing his toys into the box, at least toys that get thrown into different bins stay separated. The following diagram shows a top view of an example toy box. 
 
For this problem, you are asked to determine how many toys fall into each partition as John throws them into the toy box.

Input

The input file contains one or more problems. The first line of a problem consists of six integers, n m x1 y1 x2 y2. The number of cardboard partitions is n (0 < n <= 5000) and the number of toys is m (0 < m <= 5000). The coordinates of the upper-left corner and the lower-right corner of the box are (x1,y1) and (x2,y2), respectively. The following n lines contain two integers per line, Ui Li, indicating that the ends of the i-th cardboard partition is at the coordinates (Ui,y1) and (Li,y2). You may assume that the cardboard partitions do not intersect each other and that they are specified in sorted order from left to right. The next m lines contain two integers per line, Xj Yj specifying where the j-th toy has landed in the box. The order of the toy locations is random. You may assume that no toy will land exactly on a cardboard partition or outside the boundary of the box. The input is terminated by a line consisting of a single 0.

Output

The output for each problem will be one line for each separate bin in the toy box. For each bin, print its bin number, followed by a colon and one space, followed by the number of toys thrown into that bin. Bins are numbered from 0 (the leftmost bin) to n (the rightmost bin). Separate the output of different problems by a single blank line.

Sample Input

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

Sample Output

0: 2
1: 1
2: 1
3: 1
4: 0
5: 1

0: 2
1: 2
2: 2
3: 2
4: 2

Hint

As the example illustrates, toys that fall on the boundary of the box are "in" the box.

Source

Rocky Mountain 2003

[Submit]   [Go Back]   [Status]   [Discuss]

题目大意:给出一个矩形的左上角和右下角的坐标,矩形中有n条线段把矩形分成了n+1个部分,给出每条线段与矩形上下两条边交点的横坐标,再给出m个点的坐标,求每个部分中点的个数。

题解:计算几何的应用。

poj 2318 TOYS(计算几何)_第1张图片

刚开始想用射线法判断一个点是否在多边形的内部,但是这道题其实没必要这么麻烦,因为可以利用叉积来判断点与直线的位置关系。

叉积:

两个向量V,W的叉积等于v和w组成的三角形的有向面积的两倍,其结果是一个标量。

叉积的一个非常重要性质是可以通过它的符号判断两矢量相互之间的顺逆时针关系:

若 v×w> 0 , 则v在w的顺时针方向。
若 v×w< 0 , 则v在w的逆时针方向。
若 v×w = 0 , 则P与Q共线,但可能同向也可能反向。

那么这道题要判断一个点在一个区域中,就是判断他在左割线的顺时针方向,在右割线的逆时针方向。

总之要用到重载运算符,可能会出一些很神奇的错误。 (注意: 点-点=向量)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define N 5003
using namespace std;
int n,m,x1,y11,x2,y2,cnt[N],x,y;
struct point
{
	int x,y;
    point(){x=y=0;};
    point operator -(const point &a)
    {
    	point t; 
    	t.x=x-a.x;
    	t.y=y-a.y;
    	return t;
    }
};point lower[N];
struct vector
{
	int x,y;
	vector(){x=y=0;};
	vector operator =(const point &a)
	 {
	 	this->x=a.x; this->y=a.y;
	 	return *this;
	 }
	long long operator *(const vector &a)
	{
		return (long long)x*a.y-(long long)a.x*y;
	}
};vector v[N];
bool pd(int x,int y)
{
	return x>=x1&&x<=x2&&y<=y11&&y>=y2;
}
long long calc(vector a,vector b)
{
	return a*b;
}
int main()
{
	while (scanf("%d",&n)!=EOF)
	 {
	 	if (n==0) break;
	 	memset(cnt,0,sizeof(cnt));
	 	scanf("%d",&m); scanf("%d%d%d%d",&x1,&y11,&x2,&y2);
	 	point t; t.x=x1; t.y=y11;
	 	point k; k.x=x1; k.y=y2;
	 	v[0]=t-k; 
	 	lower[0]=k;
	 	for (int i=1;i<=n;i++)
	 	 {
	 	 	scanf("%d%d",&x,&y);
	 	 	t.x=x; t.y=y11; k.x=y; k.y=y2;
	 	 	v[i]=t-k;
	 	 	lower[i]=k;
	 	 }
	 	t.x=x2; t.y=y11; k.x=x2; k.y=y2;
	 	v[n+1]=t-k; lower[n+1]=k;
	 	for (int i=1;i<=m;i++)
	 	 {
	 	 	point t;
	 	 	scanf("%d%d",&t.x,&t.y);
	 	 	if (!pd(t.x,t.y)) continue;
	 	 	for (int j=0;j<=n;j++)
	 	 	 {
	 	 	 	vector l,r;
	 	 	 	l=t-lower[j]; r=t-lower[j+1];
	 	 	 	if (calc(l,v[j])>0&&calc(r,v[j+1])<0)
	 	 	 	{  cnt[j]++;break; }
	 	 	 }
	 	 }
	 	for (int i=0;i<=n;i++)
	 	 printf("%d: %d\n",i,cnt[i]);
	 	printf("\n");
	 }
}



你可能感兴趣的:(poj 2318 TOYS(计算几何))