我是靠谱客的博主 活泼白昼,最近开发中收集的这篇文章主要介绍J. Xingqiu‘s Joke(2021ICPC-南京)(记忆化搜索 + 数论),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

The 2021 ICPC Asia Nanjing Regional Contest

Problem

给出两个long long范围内的整数a和b(不相等),每次操作可以对a和b进行以下三个操作之一

  • a = a + 1, b = b + 1
  • a = a - 1, b = b - 1
  • a % d = 0 且 b % d = 0 且 d 是质数, a = a / d, b = b / d

问: 最小需要多少次操作才可将 a 或 b 变为 1

Input

5
4 7
9 8
32 84
11 35
2 1

Output

2
7
5
4
0

Solution

  1. 分析发现,只通过前两个操作,c(c = b - a)是不会改变的,而且a和b的公共质因数一定是c的质因数
    (假设a和b的公共质因数为g)。
  2. 所以,当我们想要进行第三个操作时,我们可以通过前两个操作来到最近的 (a / g, b / g)
  3. 观察发现,当 b - a = 1时,无论怎么进行操作,gcd(a, b) ≡ equiv 1,所以最少的操作次数是 a - 1(遇到可直接剪枝)
  4. 然后就是要注意代码的一些细节问题:
    • 看完以上几点后应该感觉到是搜索+剪枝了,但需要进行记忆化加速搜索过程
    • 对于如何记忆化,我觉得是本题的重点(具体如何记忆化看下面代码实现)
    • 可以将 (a, b)或者 是 (a, b - a) 存为 pair对,作为hash_map的第一维。
    • 但由于pair不能作为hash_map的第一维,所以需要自己写一个简单的hash函数:
      可将(a, b)哈希为一个数来存。例如:x = a × times ×(一个较大的数) + b,然后将 x 作为hash_map的第一维

Code

int c[1001], m;
int ans = inf;
unordered_map<ll, int>mp;


ll h(int a, int b)//哈希函数
{
	return a * 1e9 + b;
}

//本题不能单单将a或b当作map的第一维,
//因为可能会出现a相同但b不相同的情况。
//所以可能返回错误的答案,
//因此需要将(a, b)或者(a, b - a)作为哈希map的第一维
int dfs(int a, int b)
{
	//记忆化搜索
	if (mp[h(a, b)]) return mp[h(a, b)];

	//剪枝
	if (b - a == 1) return a - 1;
	if (a == 1) return 0;

	int ans = a - 1;//最差的情况是直接把a减到1
	for (int i = 0; i < m; i++)
		if ((b - a) % c[i] == 0)//此处要注意判断条件
		{
			int res = a % c[i];
			ans = min({ ans, 
				res + 1 + dfs(a / c[i], b / c[i]),
				c[i] - res + 1 + dfs(a / c[i] + 1, b / c[i] + 1) });
		}

	return mp[h(a, b)] = ans;
}

int main()
{
	IOS;
	int T; cin >> T;
	while (T--)
	{
		mp.clear();//可删可不删。本以为不删会速度快,没想到删掉速度快,且memory小了100倍。。可能是hash的数据多了,查找的慢了吧
		int a, b; cin >> a >> b;
		if (a > b) swap(a, b);

		int d = b - a;
		m = 0;
		for (int i = 2; i <= sqrt(d); i++)
		{
			if (d % i == 0)
			{
				c[m++] = i;
				while (d % i == 0) d /= i;
			}
		}
		if (d > 1) c[m++] = d;

		cout << dfs(a, b) << endl;
	}

	return 0;
}

最后

以上就是活泼白昼为你收集整理的J. Xingqiu‘s Joke(2021ICPC-南京)(记忆化搜索 + 数论)的全部内容,希望文章能够帮你解决J. Xingqiu‘s Joke(2021ICPC-南京)(记忆化搜索 + 数论)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部