• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
L&King
有何不可!
   首页    新随笔    联系   管理    订阅  订阅

POJ 2318 TOYS【叉积+二分】

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

计算几何入门题推荐

计算几何基础知识

题意:有一个盒子,被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;
}

 

posted @ 2016-08-01 16:02  L&King  阅读(187)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3