T637074 题解
_j_o_k_e_r_ · · 题解
本题本来要由 xwx123456 提供一道随机化题目(原因众所周知),但 xwx123456 有其他事,改为由 _j_o_k_er 提供,仍有随机化做法,预估难度为绿。
注意到题目限制比较灵活(改了又改),很难统一构造方案,所以我们充分发扬人类智慧,用随机化,把点随机出来,但也不是乱随机,是有一定道理的随机。
前
刚开始什么也没有,
此时
此时
此时
重点:此时已经有了
其中
注意到
注意到有分数,分母不能为
带入上面的例子
然后就可以敲代码了:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<random>
#include<queue>
#include<ctime>
#include<map>
#define intu unsigned long long
#define intt long long
#define dlel long double
#define dle double
using namespace std;
const int Imax=0x7fffffffL;
const long long LLmax=0x7fffffffffffffffLL;
const dle Eps=1e-4;
mt19937 _rand(time(0));
dle Mod;
int n;
dle C;
dle c;
dle a,b,x,y;
dle dis(dle x1,dle y1,dle x2,dle y2){return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));}//两点间距离
int cnt;
map<dle,map<dle,bool> > mp;//记录某个点是否走过
dle Rand(dle p)//生成[0,p] 的浮点随机数
{
int m=_rand()%3;
dle res=_rand()/pow(10,m);
return res-((int)(res/p))*p;
}
int main()
{
scanf("%d%lf",&n,&C);
n++;
Mod=2*sqrt(C/3.14);//玄学?
cnt=1;
mp[0][0]=1;
while(1)
{
if(cnt==n-1)
{
dle k=C-c;
a=b=0;
if(fabs(x-k)<=Eps) b=(x*x+y*y-k*k)/(2*y-2*k);
else a=(x*x+y*y-k*k)/(2*x-2*k);
c+=dis(x,y,a,b)+dis(a,b,0,0);
printf("%lf %lf",a,b);
return 0;
}
a=b=Mod-0.001;
while(1)
{
a=Rand(a-0.001);
b=Rand(b-0.001);
if(cnt)
{
if(!a&&!x)//直走或调头
{
a=b=Mod-0.001;
continue;
}
else if(fabs(b/a-y/x)<=Eps)//直走或调头
{
a=b=Mod-0.001;
continue;
}
}
if(c+dis(x,y,a,b)+dis(a,b,0,0)<C&&!mp[a][b])
{
mp[a][b]=1;
break;
}
}
printf("%lf %lf\n",a,b);
c+=dis(x,y,a,b);
x=a;
y=b;
cnt++;
}
return 0;
}
当然有其它做法,你完全可以把它当数学题做,用到三角函数,比较考验思维和数学功底,但难度还是在绿左右。