洛谷P4703 偷上网

题目链接


Solution

首先这题数据范围有点大,肯定是不可能每个点都枚举过去的。通过观察发现\(N\)的范围比较小,那么只需要找到点然后枚举下是否在范围内即可。然后这个点的寻找就丢给随机了。
但随意会有些缺陷,所以我们还是将四个点也特判一下。

#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <ctime>

struct Node{
    long long x,y;
}G[10];

int N;
long long l;
long long dis;

inline bool C(long long x ,long long y){

    for(register int i=1;i<=N;++i){
        long long xx = std::abs(G[i].x - x);
        long long yy = std::abs(G[i].y - y);
        xx = std::floor(std::sqrt(xx*xx+yy*yy));
        if(xx<=dis)return false;
    }       
    return true;
}
inline void print(long long a){
    if(a==0){
        printf("0.000");
        return;
    }
    long long b = a / 1000;
    printf("%lld.",b);
    b = a % 1000;
    if(b<100)putchar('0');
    if(b<10)putchar('0');
    printf("%lld",b);
}
int main(){

    scanf("%d%lld",&N,&l);
    for(register int i=1;i<=N;++i){
        double a,b;
        scanf("%lf%lf",&a,&b);
        G[i].x = (long long)(a*1000);
        G[i].y = (long long)(b*1000);
    }

    dis = (long long)((double)l / (double)N + 0.000001)*1000;
    l*=1000;
    if(C(0,0)){puts("0.000 0.000");return 0;}
    if(C(0,l)){print(0);putchar(' ');print(l);return 0;}
    if(C(l,0)){print(l);putchar(' ');print(0);return 0;}
    if(C(l,l)){print(l);putchar(' ');print(l);return 0;}

    std::srand(std::time(0));
    for(register int i=1;i<=1000000;++i){
        long long u = std::rand() % (l+1);
        long long v = std::rand() % (l+1);
        if(C(u,v)){
            print(u);putchar(' ');print(v);
            return 0;
        }
    }
    puts("GG");
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Neworld2002/p/9225701.html