Rikka with Square Numbers 2023“钉耙编程”中国大学生算法设计超级联赛(8)hdu7370

Problem - 7370

题目大意:给出两个数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;
}
相关推荐
To_OC5 小时前
LC 128 最长连续序列:别上来就排序,O (n) 解法才是这题的灵魂
javascript·算法·leetcode
05Kevin18 小时前
lk每日冒险题--数据结构6.27
算法
To_OC1 天前
从一次栈溢出报错说起,我把递归彻底扒明白了
javascript·算法·程序员
千纸鹤安安1 天前
千问Qwen-AgentWorld来了:一个语言模型搞定七大Agent场景,GPT-5.4都输了
算法
七牛开发者2 天前
MCP 到底是什么?为什么 Agent 都想接上它
算法·aigc·agent
卷无止境2 天前
C++ 的Eigen 库全解析
c++
卷无止境2 天前
现代 C++特性大盘点:一门脱胎换骨的老语言
c++·后端