在说随机化贪心前先说一下随机数据生成。
头文件ctime,cstdlib。
调用函数 rand(),srand(),其中注意windows中RAND_MAX=32767。
rand()返回0~RAND_MAX之间随机整数。
srand()初始化rand()种子。
srand((unsigned)time(0));
(long long)rand()\RAND_MAX*n //n自己定义。
先rand()一组数,对其处理使其在题目范围内,在按照题目要求对其进行判断,若可以则直接输出,return 0;若不行则从新rand(),直到可以为止。
luogu5月月赛T2
Alice 和 Bob 生活在一个l*l的正方形房子里,由于 Bob 最近沉迷隔膜,Alice 决定要限制 Bob 上网的频率。
Alice 建造了 n个无线信号屏蔽器,第i个位于 (xi,yi),屏蔽范围为 l/n.
Bob 网瘾发作按捺不住上网的冲动,找到了你,帮他找到一个位置(x,y),使得没有被 Alice 的无线信号屏蔽器覆盖。
输入输出格式
第一行两个整数 n,l(1≤n≤10,1≤l≤1e5),分别表示无线信号屏蔽器的个数和房子的大小。
接下来n行,每行2个数,分别是 xi,y(0≤xi,yi≤l) ,意义如上所述。
如果可以找到,输出两个数 x,y(0≤x,y≤l)x, y(0 \leq x, y \leq l)x,y(0≤x,y≤l) ,意义如上所述,如果有多组解,输出任意一组即可。如果你输出的解满足到任意一个屏蔽器的距离都不小于 ln+10−6\frac{l}{n} + 10^{-6}n
l+10−6 ,则视为正确。
否则输出 “GG”。
输入输出样例
输入样例#1:
1 1
0.000 0.000
输出样例#1:
0.999 0.999
输入样例#2:
1 2
1.000 1.000
输出样例#2:
GG
输入样例#3
2 2
0.000 0.000
2.000 2.000
输出样例#3:
1.000 1.000
如果n=1,则枚举一下四个角,如果都不可行,一定无解,否则就找到了合法点。
如果n≥2,则圆的总面积一定小于正方形的面积,每次随机一个点,判断是否可行。
上代码
#include
using namespace std;
int n,m;
double x[11],y[11],ax,ay,t;
bool flag=0;
inline int read(){
int ret=0;
char c=getchar();
bool flag=false;
while(c<'0'||'9'if(c=='-') flag=true;
c=getchar();
}
while('0'<=c&&c<='9') ret=ret*10+c-'0',c=getchar();
return flag?-ret:ret;
}
double dist(double a,double b,double c,double d){
return (double)sqrt((a-c)*(a-c)+(b-d)*(b-d));
}
inline void work(){
int aa=rand()%(n*100),bb=rand()%(n*100);
double a=(double)aa/100,b=(double)bb/100;
for (register int i=1;i<=m;i++){
double d=dist(a,b,x[i],y[i]);
if (d<=t+1e-9) return ;
}
printf("%.3lf %.3lf\n",a,b);
flag=1;
}
int main(){
srand(time(0));
m=read(),n=read();
t=n/m;
for(register int i=1;i<=m;i++)
scanf("%lf%lf",&x[i],&y[i]);
if(t> sqrt(2)*n){
printf("GG\n");
return 0;
}
int T=100000;
while(T--){
work();
if(flag) return 0;
}
cout<<"GG";
return 0;
}