Description
Input
Output
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
题意是有m个玩具(看成一个点),有n个板子把一个矩形区域隔成n+1个区域,问每个区域内有多少个玩具。
利用叉积判断点在一条线段的左边还是右边,可以直接暴力循环找在哪个区域,也可以二分。
叉积:为x1*y2 - x2*y1
叉积的结果也是一个向量,是垂直于向量a,b所形成的平面,如果看成三维坐标的话是在 z 轴上,上面结果是它的模。
方向判定:右手定则,(右手半握,大拇指垂直向上,四指右向量a握向b,大拇指的方向就是叉积的方向)
若 a x b > 0表示a在b的顺时针方向上
若 a x b < 0表示a在b的逆时针方向上
若 a x b == 0表示a在b共线,但不确定方向是否相同
如果要判断一个点在线段的左边还是右边,只用计算一下这个点指向线段上面那个点的向量与这个点指向线段下面那个点的向量的叉积,如果是负这点就在线段的左边,如果是正就在右边。
#include
#include
#include
#include
#include
#include
using namespace std;
struct Point
{
int x,y;
Point(){}
Point(int _x,int _y)
{
x = _x;y = _y;
}
Point operator -(const Point &b)const
{
return Point(x - b.x,y - b.y);
}
int operator *(const Point &b)const
{
return x*b.x + y*b.y;
}
int operator ^(const Point &b)const
{
return x*b.y - y*b.x;
}
};
struct Line
{
Point p1,p2;
Line(){}
Line(Point _p1,Point _p2)
{
p1 = _p1;
p2 = _p2;
}
};
int xmult(Point p0,Point p1,Point p2) //p0p1 X p0p2
{
return (p1-p0)^(p2-p0);
}
int n;
Line a[5500];
int ans[5500];
int binarysearch(Point p)
{
int l = 0,r = n;
int ans = r;
while(l <= r)
{
int mid = (l+r)/2;
if(xmult(p,a[mid].p1,a[mid].p2) < 0)
{
ans = mid;
r = mid - 1;
}
else
l = mid + 1;
}
return ans;
}
int main(void)
{
int m,x,y,xx,yy,i,j;
int first = 1;
while(scanf("%d",&n)==1)
{
if(n == 0)
break;
if(first == 1)
first = 0;
else
printf("\n");
scanf("%d %d%d%d%d",&m,&x,&y,&xx,&yy);
for(i=0;i 0 && xmult(p,a[j].p1,a[j].p2) < 0)
{
ans[j]++;
break;
}
}
/*
int t = binarysearch(p); //二分找区间
ans[t]++;
*/
}
for(i=0;i<=n;i++)
printf("%d: %d\n",i,ans[i]);
}
return 0;
}