题目大意:给你一个矩形和一些线段,给的这些线段将矩形分割为从左到右的若干个部分(不会相交,点不会再线上,题意给出了),之后给出一些玩具的坐标,求分割的若干部分每个部分的玩具数量。
题解:这是一个计算几何的水题,考一些基础问题,我们注意,题目上给线段的顺序是从左到右给出的,我们可以考虑的是每一个点(玩具)是在这条线的左边还是右边,(一定会存在一个分界使它的左边的线段都在玩具的右边,它右边的玩具都在玩具的左边)
于是我们能想出来这种情况下我们要用二分来写:
然后我们根据叉积判断点和线段的关系(我们可以将点减去线段的起点和原线段组成两个同七点的向量,然后我们根据叉积的性质:
若P×Q > 0 , 则P在Q的顺时针方向;
若P×Q < 0 , 则P在Q的逆时针方向;
若P×Q = 0 , P与Q共线,可能是同向也可能是反向
因为题目上说了,玩具保证不会落在分界线上,所以不用考虑)
特别注意:本题的数组有点儿多吧,注意初始化每一个数组。
AC代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int mx = 666666;
int u[mx] , v[mx] , ans[mx];
int chachen(int x1 , int y1 , int x2 , int y2)
{
return x1 * y2 - x2 * y1;
}
int main()
{
int n , m , x1 , y1 , x2 , y2 , flag = 0 ;
while(scanf("%d%d%d%d%d%d",&n,&m,&x1,&y1,&x2,&y2) == 6)
{
if(flag)
puts("");
flag = 1;
memset(ans,0,sizeof(ans));
for(int i = 0 ; i < n ; i ++)
{
scanf("%d %d",&u[i],&v[i]);
}
int x , y ;
for(int i = 1 ; i <= m ; i ++)
{
cin>>x>>y;
int high = n , mid , low = 0 ;
while(low < high)
{
mid = (low + high) / 2 ;
if(chachen(u[mid] - x , y1 - y , v[mid] - x , y2 - y) <= 0)
high = mid;
else
low = mid + 1 ;
}
ans[low]++;
}
for(int i = 0 ; i <= n ; i ++)
{
printf("%d: %d\n",i,ans[i]);
}
}
return 0 ;
}
有的可能就是sort扫一遍然后输出就能过,可能使后台数据太水吧,那个我看要900多Ms,但是用二分的话差不多500Ms运行完