码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 2318 TOYS【叉积+二分】

时间:2016-08-01 17:33:59      阅读:141      评论:0      收藏:0      [点我收藏+]

标签:

今天开始学习计算几何,百度了两篇文章,与君共勉!

计算几何入门题推荐

计算几何基础知识

题意:有一个盒子,被n块木板分成n+1个区域,每个木板从左到右出现,并且不交叉。 有m个玩具(可以看成点)放在这个盒子里,问每个区域分别有多少个玩具。

思路:首先,用叉积判断玩具是否在木板的左边,再用二分找到符合的最右边的木板,该木板答案加一。

#include<stdio.h>
#include<string.h>
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;
    }
};
int cal(point p0,point p1,point p2){//小于0表示在p1处左折,大于0右折,等于0同线 
    return (p1-p0)^(p2-p0);
}
const int N=5555;
point s[N],e[N];
int ans[N];
int main(){
    int n,m,x1,x2,y1,y2;
    int x3,x4,i,f=0;
    while(~scanf("%d",&n)&&n){
        scanf("%d%d%d%d%d",&m,&x1,&y1,&x2,&y2);
        if(!f)    f=1;
        else    puts("");
        memset(ans,0,sizeof(ans));
        for(i=0;i<n;i++){
            scanf("%d%d",&x3,&x4);
            s[i]=point(x3,y1);
            e[i]=point(x4,y2);
        }
        s[n]=point(x2,y1);
        e[n]=point(x2,y2);
        while(m--){
            int l=0,r=n,mid,x,y,tmp;
            scanf("%d%d",&x,&y);
            point p=point(x,y);
            while(l<=r){
                mid=(l+r)>>1;
                if(cal(p,s[mid],e[mid])<0){
                    tmp=mid;
                    r=mid-1;
                }
                else
                    l=mid+1;
            }
            ans[tmp]++;
        }
        for(i=0;i<=n;i++){
            printf("%d: %d\n",i,ans[i]);
        }
    }
    return 0;
}

 

POJ 2318 TOYS【叉积+二分】

标签:

原文地址:http://www.cnblogs.com/L-King/p/5726184.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!