叉积的性质 【poj2318】 TOYS

题目大意:
给定一个矩形,中间有n块板把这个矩形分成n+1块,从0开始编号。
保证按照顺序给出并且没有相交。
给定m个点,询问每一个块内有多少个点。

题目分析:
对于每一个点二分所有的线段,然后利用叉积的性质判断它在这条线的左边还是右边,统计答案。
时间复杂度O(mlogn)
(水题一枚╮(╯_╰)╭,我这种蒟蒻也就能做这种题了QAQ)

代码如下:

#include<cstdio>
#include<cstring>
#define N 5005
using namespace std;
struct point{
    int x,y;
    point(int x=0,int y=0):x(x),y(y){}
}tmp;
struct line{
    point a,b;
}a[N];
int n,m,x1,x2,y1,y2;
int ans[N];
int Cross_product(point p1,point p2,point p0)
{
    return (p1.x-p0.x)*(p2.y-p0.y)-(p1.y-p0.y)*(p2.x-p0.x);
}
int bin(point c)
{
    int l=0,r=n,ans=0;
    while(l<=r)
    {
        int mid=l+r>>1;
        if(Cross_product(c,a[mid].a,a[mid].b)>0)
           l=mid+1,ans=mid;
        else r=mid-1;
    }
    return ans;
}
int main()
{
for(;;)
{
    scanf("%d",&n);
    if(!n) break;
    memset(ans,0,sizeof(ans));
    scanf("%d",&m);
    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
    a[0].a=point(x1,y1);
    a[0].b=point(x1,y2);
    a[n+1].a=point(x2,y1);
    a[n+1].b=point(x2,y2);
    for(int i=1;i<=n;i++)
    {
        scanf("%d%d",&x1,&x2);
        a[i].a=point(x1,y1);
        a[i].b=point(x2,y2);
    }
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&tmp.x,&tmp.y);
        ans[bin(tmp)]++;
    }
    for(int i=0;i<=n;i++)
        printf("%d: %d\n",i,ans[i]);
    printf("\n");
}
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值