poj 2318 TOYS 叉乘 二分查找


把一个矩形分成多个格子,矩形上分布多个点,求每个格子的拥有的点数。
简单的叉乘运用,查找时要用二分查找,不然很容易超时。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
using namespace std;
double y1,y2,p[5005][2];
double judge(int j,double x,double  y)
{
        return (p[j][1]-p[j][0])*(y-y1)-(y2-y1)*(x-p[j][0]); //叉乘判断方向,大于0线在点的左方,小于0线在点的右方。
}        
int main()
{
        int ans[5005],i,j,n,m,low,high,mid;
        double x,y,x1,x2;
        while(scanf("%d",&n),n)
        {
                memset(ans,0,sizeof(ans));
                scanf("%d%lf%lf%lf%lf",&m,&x1,&y1,&x2,&y2);
                for(i=1;i<=n;i++)
                        scanf("%lf%lf",&p[i][0],&p[i][1]);
                p[0][0]=x1;p[0][1]=x1;
                p[n+1][0]=x2;p[n+1][1]=x2;
                for(i=0;i<m;i++)
                {
                        low=0;high=n+1;
                        mid=(low+high)/2;
                        scanf("%lf%lf",&x,&y);
                        if(judge(0,x,y)==0)     //若点在矩形的左边界上 直接确定位置。
                                mid=0;
                        else if(judge(n+1,x,y)==0) //同理若点在矩形的右边界上直接确定位置。
                                mid=n;
                        else
                        {
                                while(low<high)  //二分查找
                                {
                                        if(judge(mid,x,y)<0)
                                        {
                                                high=mid-1;
                                                mid=(low+high)/2;
                                        }
                                        else
                                        {
                                                low=mid+1;
                                                mid=(low+high)/2;
                                        }
                                }
                                if(judge(mid,x,y)<0)  //查到最后时还要最终判断一下mid位置的线在点的左边或是右边,若在点的右边要自减1。
                                        mid--;
                        }
                        ans[mid]++;
                }
                for(i=0;i<=n;i++)
                        printf("%d: %d\n",i,ans[i]);
                printf("\n");
                
        }
        return 0;
}

posted @ 2011-04-14 17:44  CoderZhuang  阅读(128)  评论(0编辑  收藏  举报