洛谷月赛——随机算法

洛谷的月赛第二题:

偷上网

 

题目描述

Alice 和 Bob 生活在一个 l \times ll×l 的正方形房子里,由于 Bob 最近沉迷隔膜,Alice 决定要限制 Bob 上网的频率。

Alice 建造了 nn 个无线信号屏蔽器,第 ii 个位于 (x_i, y_i)(xi​,yi​) ,屏蔽范围为 \frac{l}{n}nl​ 。

Bob 网瘾发作按捺不住上网的冲动,找到了你,帮他找到一个位置 (x, y)(x,y) ,使得没有被 Alice 的无线信号屏蔽器覆盖。

输入输出格式

输入格式:

 

 

 

第一行两个整数 n, l(1 \leq n \leq 10, 1 \leq l \leq 10^5)n,l(1≤n≤10,1≤l≤105) ,分别表示无线信号屏蔽器的个数和房子的大小。

接下来 nn 行,每行 22 个数,分别是 x_i, y_i(0 \leq x_i, y_i \leq l)xi​,yi​(0≤xi​,yi​≤l) ,意义如上所述。

 

输出格式:

 

 

 

如果可以找到,输出两个数 x, y(0 \leq x, y \leq l)x,y(0≤x,yl) ,意义如上所述,如果有多组解,输出任意一组即可。如果你输出的解满足到任意一个屏蔽器的距离都不小于 \frac{l}{n} + 10^{-6}nl​+10−6 ,则视为正确。

否则输出 "GG"。

最开始的懵逼了半天,然后想用随机数的方法做,但是由于rand给出的是整数,我怎么弄都弄不好范围,所以最后放弃了

听到题解的时候竟然真的是一个随机算法,于是兴致勃勃的想了想。emm

才知道原来rand有一个最大值是rand_max,我用随机到的数x/rand_max * 范围l,就行了,当前随机到的占总共的比例乘范围就是我想要的数啦。这道题数据貌似比较水。几千次就过了

主要收获就是对rand的使用吧。

对于整数来说随机[x,y]  rand()%(y-x+1)+x;

    小数就是[0,range]  ((double)rand()/RAND_MAX)*range

最后的话就是上码

#include<iostream>
#include<cmath>
#include<cstdlib>
#include<ctime>
#define delta 1e-6
using namespace std;
int n,l;
bool ok;
double r;
struct circle
{
double x,y;
}pos[11];
double getdis(double x1,double y1,double x2,double y2)
{
return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
}
bool judge(double x,double y)
{
for(int i=1;i<=n;i++)
{
if(getdis(pos[i].x,pos[i].y,x,y)<r+delta)return false;
}
return true;
}
int main()
{
srand(time(NULL));
cin>>n>>l;
r=l/n;
for(int i=1;i<=n;i++)cin>>pos[i].x>>pos[i].y;
for(int i=1;i<=5000;i++)
{
double nx=((double)rand()/RAND_MAX)*l;
double ny=((double)rand()/RAND_MAX)*l;
if(judge(nx,ny))
{
cout<<nx<<" "<<ny;
return 0;
}
}
cout<<"GG";
return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值