定义:平面上的三点P1(x1,y1),P2(x2,y2),P3(x3,y3)的面积量:
|x1 x2 x3|
S(P1,P2,P3) = |y1 y2 y3| = (x1-x3)*(y2-y3) - (y1-y3)(x2-x3)
|1 1 1 |
当P1P2P3逆时针时S为正的,当P1P2P3顺时针时S为负的。
令矢量的起点为A,终点为B,判断的点为C,
如果S(A,B,C)为正数,则C在矢量AB的左侧;
如果S(A,B,C)为负数,则C在矢量AB的右侧;
如果S(A,B,C)为0,则C在直线AB上。
对于有公共端点的线段p0p1和p1p2,通过计算(p2- p0) × (p1 - p0)的符号便可以确定折线段的拐向:
若(p2- p0) × (p1 - p0) > 0,则p0p1在p1点拐向右侧后得到p1p2。
若(p2- p0) × (p1 - p0) < 0,则p0p1在p1点拐向左侧后得到p1p2。
若(p2- p0) × (p1 - p0) = 0,
则
p0
、
p1
、
p2
三点
共线。
所以第二种判断方法为:
bool chaji(dia p0,dia p1,dia p2)
{
if(((p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x))<0)//p0 p2 分别表示线段的两端,p1为要判断的点
{
return true;
}
else
return false;
}
poj 2318 toy
题意:给出n个板子,分隔成n+1块区域,再给出m个玩具,求在每个区域中有多少玩具。
解题思路: 对于每一个玩具,依次从左到右判断每个玩具是不是在该板子左侧,如果在,则将此位置数量加1,注意最后一块区域,一定要计数。
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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct lin
{
dia a;//a dixia
dia b;
}line[maxn];//上边 下边
bool chaji(dia p0,dia p1,dia p2)//判断点在直线左侧
{
if(((p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x))<0)
{
return true;
}
else
return false;
}
void judge(dia pp)
{
for(int i = 0; i < n; i++)
{
if(chaji(line[i].b,pp,line[i].a)>0)
{
coun[i]++;
return ;
}
}
coun[n]++;
return ;
}
int main()
{
int c,d,e,f;
while(cin>>n&&n)
{
memset(coun,0,sizeof(coun));
cin>>m;
cin>>c>>d>>e>>f;
for(int i = 0; i < n; i++)
{
cin>>line[i].a.x;
cin>>line[i].b.x;
line[i].b.y = f;
line[i].a.y = d;
}
dia pp;
for(int i = 0; i < m; i++)
{
cin>>pp.x>>pp.y;
judge(pp);
}
for(int i = 0; i <= n; i++)
{
printf("%d: %d\n",i,coun[i]);
}
printf("\n");
}
}
poj 2398(上一道题的进阶)
题意:板子是无序的,最终输出相同玩具区域的个数
稍作改变:
代码如下:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
struct lin
{
dia a;//a dixia
dia b;
}line[maxn];//上边 下边
bool cmp(const lin &u,const lin &v)
{
if(u.a.x!=v.a.x)
return u.a.x // return u.a.y}
bool chaji(dia p0,dia p1,dia p2)//判断点在直线左侧
{
if(((p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x))<0)
{
return true;
}
else
return false;
}
int cnt[5005], ans[5005];
void judge(dia pp)
{
for(int i = 0; i < n; i++)
{
if(chaji(line[i].b,pp,line[i].a)>0)
{
coun[i]++;
return ;
}
}
coun[n]++;
return ;
}
int main()
{
int c,d,e,f;
while(cin>>n&&n)
{
memset(coun,0,sizeof(coun));
memset(ans,0,sizeof(ans));
cin>>m;
cin>>c>>d>>e>>f;
for(int i = 0; i < n; i++)
{
cin>>line[i].a.x;
cin>>line[i].b.x;
line[i].b.y = f;
line[i].a.y = d;
}
sort(line,line+n,cmp);
dia pp;
for(int i = 0; i < m; i++)
{
cin>>pp.x>>pp.y;
judge(pp);
}
/* for(int i = 0; i <= n; i++)
{
printf("%d: %d\n",i,coun[i]);
}*/
int t = 0;
for(int i = 0; i <= n; i++)
{
ans[coun[i]]++;
}
printf("Box\n");
for(int i = 1; i < n; i++)
{
if(ans[i]!=0)
{
printf("%d: %d\n",i,ans[i]);
}
}
}
}
判断点在凸多边形内部:
原理:凸多边形内部的点都在凸多边形的边所在的向量的同一侧(前提是计算边所在的向量时采用的是同一个方向,同为顺时针或者同为逆时针),利用叉积求解。
假设四边形四个顶点依次为A(x1,y1),B(x2,y2),C(x3,y3),D(x4,y4),待判断的点为P(x,y),如果点P在四边形内部,则向量AB * AP(注意:1.这是求叉积;2.AB、AP均为向量,也就等于(x2-x1) * (y-y1)-(y2-y1) * (x-x1))的值与BC*BP、CD * CP、DA * DP的值同号(若有等于零的情况,则表示P在边上,可以根据自己的喜好把它当做是内部或者外部),即四个值同为正或者同为负,则点P在ABCD内部,否则在外部。
private boolean isPointInRect(int x, int y) {
final Point A = mLBPoint;
final Point B = mLTPoint;
final Point C = mRTPoint;
final Point D = mRBPoint;
final int a = (B.x - A.x)*(y - A.y) - (B.y - A.y)*(x - A.x);
final int b = (C.x - B.x)*(y - B.y) - (C.y - B.y)*(x - B.x);
final int c = (D.x - C.x)*(y - C.y) - (D.y - C.y)*(x - C.x);
final int d = (A.x - D.x)*(y - D.y) - (A.y - D.y)*(x - D.x);
if((a > 0 && b > 0 && c > 0 && d > 0) || (a < 0 && b < 0 && c < 0 && d < 0)) {
return true;
}
// AB X AP = (b.x - a.x, b.y - a.y) x (p.x - a.x, p.y - a.y) = (b.x - a.x) * (p.y - a.y) - (b.y - a.y) * (p.x - a.x);
// BC X BP = (c.x - b.x, c.y - b.y) x (p.x - b.x, p.y - b.y) = (c.x - b.x) * (p.y - b.y) - (c.y - b.y) * (p.x - b.x);
return false;
}
https://blog.csdn.net/liangzhaoyang1/article/details/51090370# 判断线段相交