题目大意:给出两个数a,b,每次操作可以使其中一个数加上或减去一个任意的完全平方数,问要使a,b相等需要的最少操作次数是多少
1<=a,b<=1e9,a!=b
思路:我们可以将问题转化为将a和b的差w变为0需要的最少操作数,如果w是0显然只需要1次操做。
然后我们考虑2次操作的情况,先考虑做减法,也就是考察是否存在a,b,使得,假设b=a-1,将b代入化简可以发现左式等于2b-1,也就是左式的结果为所有的奇数,那么所有的不是完全平方数的数的最少操作数也就是2。
设b=a-2,左式等于4a-4,也就是所有的4的倍数,那么所有4的倍数所需要的最少操作数也就是2,当b=a-3,b=a-4...时,可以发现得到的结论已经被包含在了我们上面得出过的结论里。
然后考虑做加法,也就是考察是否存在a,b,使得,这时给b赋值不好找规律,那我们就从1~sqrt(w)枚举a,看b是否是完全平方数
考虑操作次数大于2的情况,因为已知奇数的操作次数不超过2,所以偶数最坏就是从相邻的奇数+1得到,操作次数为3,所以不满足上面所有条件的数就直接输出3即可
cpp
//#include<__msvc_all_public_headers.hpp>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
int n;
bool check(int x)
{//检查一个数是否是完全平方数
int temp = sqrtl(x);
for (int i = temp - 5; i <= temp + 5; i++)
{
if (i * i == x)
{
return 1;
}
}
return 0;
}
void solve()
{
int a, b, w;
cin >> a >> b;
w = abs(a - b);
if (check(w))
cout << 1;//完全平方数是1
else if (w & 1 || w % 4 == 0)
{//奇数和4的倍数是2
cout << 2;
}
else
{
int x = sqrtl(w);
for (int i = 1; i * i <= w; i++)
{
if (check(w - i * i))
{
cout << 2 << endl;//找到a方+b方=w就是2
return;
}
}
cout << 3;都不满足就是3
}
cout << endl;
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
solve();
}
return 0;
}