Teacher Bo HDU - 5762 (思维)

Teacher BoBo is a geography teacher in the school.One day in his class,he marked NN points in the map,the ii-th point is at (Xi,Yi)(Xi,Yi).He wonders,whether there is a tetrad (A,B,C,D)(A<B,C<D,ACorBD)(A,B,C,D)(A<B,C<D,ACorBD) such that the manhattan distance between A and B is equal to the manhattan distance between C and D.

If there exists such tetrad,print “YES”,else print “NO”.
Input
First line, an integer TT. There are TT test cases.(T≤50)(T≤50)

In each test case,the first line contains two intergers, N, M, means the number of points and the range of the coordinates.(N,M≤105)(N,M≤105).

Next N lines, the ii-th line shows the coordinate of the ii-th point.(Xi,Yi)(0≤Xi,Yi≤M)(Xi,Yi)(0≤Xi,Yi≤M).
Output
TT lines, each line is “YES” or “NO”.
Sample Input
2
3 10
1 1
2 2
3 3
4 10
8 8
2 3
3 3
4 4
Sample Output
YES
NO
这道题实际上直接去暴力去做就可以了,但是很多人绝对仍为暴力是过不了的,然后一直迟迟没有动手,实际上写的形式的确很向 O(N2) ,但是我后来分析来一下,实际上复杂度只会到 O(M) ,我的做法就是设置一个布尔数组 dis[d] Z,含义是d这种长度的路径是否出现过,只要出现过就为true,如果再次出现那答案为YES

换言之,当 (N2N)>4M ,答案必为YES

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
bool dis[200005];
struct point
{
    int x,y;
}p[100005];
int getDis(point p1,point p2)
{
    return abs(p1.x-p2.x)+abs(p1.y-p2.y);
}
int main()
{
    int t;
    int n,m;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        bool sign=false;
        memset(dis,false,sizeof(dis));
        for(int i=0;i<n;i++)//时间复杂度不是对这个两层for循环分析,而是dis这个数组的长度
        {
            scanf("%d%d",&p[i].x,&p[i].y);
            if(!sign)
            {
                for(int j=0;j<i;j++)
                {
                    int d=getDis(p[i],p[j]);
                    if(dis[d])
                    {
                        sign=true;
                        break;
                    }
                    else
                        dis[d]=true;

                }
            }
        }
        if(sign)
            printf("YES\n");
        else
            printf("NO\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值