zoukankan      html  css  js  c++  java
  • 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;
    }

  • 相关阅读:
    多个文件目录下Makefile的写法
    通用多目录makefile的写法
    一个简单的通用Makefile实现
    Eclipse + CDT + YAGARTO + J-Link,STM32开源开发环境搭建与调试
    Eclipse-cdt 配合 gdbserver 进行 arm 程序远程调试 上
    Eclipse-cdt 配合 gdbserver 进行 arm 程序远程调试 下
    WiEngine+Eclipse+CDT+Sequoyah实现c++编程智能感知提示
    Docker 常用命令总结
    很好用的取代 PuTTY 的SSH远程登陆软件 Termius
    [转]如何优雅地进行参数校验?有什么提高代码稳壮性的方式?
  • 原文地址:https://www.cnblogs.com/zxj015/p/2740235.html
Copyright © 2011-2022 走看看