题意
A robot is placed in a cell (0,0) of an infinite grid. This robot has adjustable length legs. Initially, its legs have length 1.
Let the robot currently be in the cell (x,y) and have legs of length mm. In one move, it can perform one of the following three actions:
- jump into the cell (x+m,y);
- jump into the cell (x,y+m);
- increase the length of the legs by 1, i. e. set it to m+1
What's the smallest number of moves robot has to make to reach a cell (a,b)(a,b)?
这题需要处理的就是当步长不被距离整除的时候,余数怎么计算
步长不被距离整除 == 余数 < 步长
解决问题的关键就是 : 在步长变长的过程中把不被整除的地方先走完
,如最终步长要变为P, 假设我们要从(0,0)走到(0,a),当前步长为now
1.a < P , 那么把 now 变成 a, 再一步到a, 这样的需要是 变长的步数 + 走的步数 = a - now + 1
2.a % P == 0 把now 变成 P , 然后走一步 , 同样也是 a - now + a / p
3.a % P != 0 把now 变成 a % P, ,然后走一步到a % P处,再加到P,走 a / p
共a % P - now + 1 + P - now + a / p;
因为最终 now 要变为P, 所以变长的操作总共肯定为 P - 1,即上方删除的累计为 P - 1,可以发现,不被整除的地方会多走一步,只需要判断这一个地方即可,枚举 步长,找出最小值
粗略计算步长, a / P + b / P + P - 1 最小, 在 P = sqrt(a + b) 时大概最小
#include<iostream>
#include<cmath>
#include<algorithm>
#define int long long
using namespace std;
signed main()
{
int t;
cin >> t;
while(t --)
{
int a, b;
cin >> a >> b;
int ans = 10000000000;
int ed = sqrt(2000000000);
for (int i = 1; i <= ed; i++)
ans = min(ans, (a + i - 1) / i + (b + i - 1) / i + i - 1);
cout << ans << endl;
}
}