原题链接
https://ac.nowcoder.com/acm/contest/11259/K
题目大意
在二维平面上,在
x
x
x轴方向上每
w
w
w km画一条竖线,在
y
y
y轴方向上每
d
d
d km画一条横线,这些线将平面分割为若干个
w
×
d
w\times d
w×d大小的矩形区域。
求任意点开始,以任意形式的路径行驶
π
\pi
π km,最多可以访问到多少区域。
题解
首先我们从一个点出发,开始我们可以花费极小的代价经过4个区域,这个代价小到可以忽略不计。
由于两点之间线段最短,所以我们从一个区域到另一个区域尽量走直线并经过格点,这样就可以花费一个极小代价从而经过更多的区域。
有两种走法:
①走边:沿着线经过区域,每次到新的区域时花费极小代价经过相邻的另一个新的区域,如图:
②走对角线:沿着对角线走,到达新区域时花费极小代价经过相邻的区域,如图:
注:蓝色区块为起始时花费极小代价经过的四个区域,绿色块到达新区域时花费极小代价经过的区域。
此时我们假设 a = m i n ( w , d ) , b = w 2 + d 2 a=min(w,d),b=\sqrt{w^2+d^2} a=min(w,d),b=w2+d2,便可以得到 a x + b y ≤ π ( 0 ≤ x ≤ π a , 0 ≤ y ≤ π b ) ax+by\le\pi(0\le x\le \frac{\pi}{a},0\le y\le \frac{\pi}{b}) ax+by≤π(0≤x≤aπ,0≤y≤bπ)(且x,y都为非负整数),则经过的区域数为 3 a x + 2 b y 3ax+2by 3ax+2by。
所以两种方法经过一个区域的代价分别为
a
2
,
b
3
\frac{a}{2},\frac{b}{3}
2a,3b,我们需要通过这个代价计算最优解。
①
a
2
<
b
3
\frac{a}{2}<\frac{b}{3}
2a<3b,将
2
a
x
→
3
b
y
2ax\rightarrow 3by
2ax→3by得到更优解;
②
a
2
>
b
3
\frac{a}{2}>\frac{b}{3}
2a>3b,将
3
b
y
→
2
a
x
3by\rightarrow 2ax
3by→2ax得到更优解;
③
a
2
=
b
3
\frac{a}{2}=\frac{b}{3}
2a=3b,此时
2
a
x
=
3
b
y
2ax=3by
2ax=3by,两者之间可以互相转化;
所以当 x ≥ 3 x\ge 3 x≥3且 y ≥ 2 y\ge 2 y≥2时,大于这部分的值是可以互相转化且不会影响最终解,所以我们只需要枚举 x < 3 x<3 x<3且 y < 2 y<2 y<2的部分并寻找最优解即可。
由于题目给出的 w , d w,d w,d的精度控制在 1 0 − 8 10^{-8} 10−8之内,所以我们只需要用 d o u b l e double double类型的变量存 π \pi π的值即可。(什么?你不会计算 π \pi π的值?不会吧不会吧,不会还有人不会背 π \pi π小数点后15位吧(doge))
参考代码
#include<bits/stdc++.h>
#define ll long long
#define FOR(i,n,m) for(int i=n;i<=m;i++)
using namespace std;
int T;
int main()
{
scanf("%d",&T);
double pie=acos(-1);
while(T--)
{
double n,m,num1,num2;
ll ans=0;
scanf("%lf%lf",&n,&m);
num1=min(n,m);num2=sqrt(n*n+m*m);
FOR(i,0,2)
{
if(pie>=num1*i)
{
ll g=(pie-num1*i)/num2;
ans=max(ans,i*2+g*3);
}
if(pie>=num2*i)
{
ll g=(pie-num2*i)/num1;
ans=max(ans,g*2+i*3);
}
}
printf("%lld\n",ans+4);
}
}