POJ 2002 快速查找

这是一道几何+快速查找的题目。


根据扩展方向的不同,主要有两种坐标的形式。我们只需要选择想一个方向的扩展,因为我们需要枚举所有的节点。但是这要做还是会有重复的,根据AB求CD坐标和根据AD求BC坐标,其实这两种确定的是一个正方形,所以最后的结果需要除以2。

    另,枚举两个点,求得另外两个点,判断求出的这两个点是否在给定的点集中。我使用的是二分查找策略,首先需要对坐标先按照x排序,x相等的话,按照y进行排序。查找过程先对x进行二分的查找,当查找到x时候,但是对应的y坐标不相等时,需要向左右两个方向分别进行查找x值相等的所有组合,判断y值是否和目标y值相等。举例来说,有以下几个点:(0,5) (1,2) (1,3) (1,4) (2,0) 要查找的目标点为(1,4)我们首先二分的时候查找到的是(1,3),这时候需要向两边分别进行查找,具体见代码。

//11219609	c00h00g	2002	Accepted	396K	1032MS	G++	1975B	2013-01-29 17:09:38
//二分跑了一千多毫秒 
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;

struct Node{
    int x,y;
};
Node point[1005];
int n;

bool bsearch(Node des){
    int l=0,r=n-1;
    while(l<=r){
        int mid=(l+r)>>1;
        if(point[mid].x<des.x)
            l=mid+1;
        else if(point[mid].x>des.x)
            r=mid-1;
        else if(point[mid].x==des.x){
            //继续查找
            if(point[mid].y==des.y)
                return 1;
            else if(point[mid].y>des.y){
                int i=mid-1;
                while(i>=0&&point[i].x==des.x){
                    if(point[i].y==des.y)
                        return 1;
                    else
                        i--;
                }
                return 0;
            }
            else if(point[mid].y<des.y){
                int i=mid+1;
                while(i<n&&point[i].x==des.x){
                    if(point[i].y==des.y)
                        return 1;
                    else
                        i++;
                } 
                return 0;
            }
        }
    }
    return 0;
}

int cmp(Node p1,Node p2){
    if(p1.x!=p2.x)
        return p1.x<p2.x;
    else
        return p1.y<p2.y;
}
int main(){
    while(scanf("%d",&n)&&n){
        for(int i=0;i<n;i++)
            scanf("%d%d",&point[i].x,&point[i].y);
        sort(point,point+n,cmp);
        int res=0;
        for(int i=0;i<n;i++)
            for(int j=0;j<i;j++){
                int x1=point[i].x;int y1=point[i].y;
                int x2=point[j].x;int y2=point[j].y;
                int x3=x1+y1-y2;int y3=y1+x2-x1;
                int x4=x2+y1-y2;int y4=y2+x2-x1;
                Node tmp1;tmp1.x=x3;tmp1.y=y3;
                Node tmp2;tmp2.x=x4;tmp2.y=y4;
                if(bsearch(tmp1)&&bsearch(tmp2))
                    res++;
            }
        printf("%d\n",res/2);
    }    
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值