洛谷P13016 [GESP202506 六级] 最大因数 题解

题目传送门

题目已经说得很清楚了,但要是想要做出这道题,就需要有 因数意识,意思是一旦发现题目中有类似‘因数’等题眼,就可以考虑分解质因数(bushi) 。于是乎-

思路

举个栗子:12和14。

根节点一定是1,所以通过画图可以得到他们的距离是5(自己画去)。然后我们再通过上文的因数意识分解他们:

  • $12=223$
  • $14=2*7$

答案竟然正好是他们分解的质因数的因数数量和!!!再来一组:18和108。

  • $ 18=233$
  • $108=22333$

这回怎么不对了?答案明明是4!作者你竟然骗我!

A:你没发现后面有两个3?消掉不就行了。

Q:那前面还有相同2怎么办?

A:要从后往前找最大的质因数消掉,2就不用管了。

Q:意思就是说从后往前最大的质因数能消就消呗。可为什么呢?

A:这个你得看后面的解析。

总结一下,先把两个数进行因式分解,然后从后往前找最大的质因数消,最后统计两数只因数之和就行了,可以用栈来实现。

code(No (Ctrl+C)ing)

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define hahahahahaha return
int q;

signed main() {
	cin >> q;
	while (q--) {
		int x, y;
		cin >> x >> y;
		stack<int> s, ss;
		for (int i = 2; i * i <= x;) {//因式分解存到栈里
			if (x % i == 0) {
				s.push(i);
				x /= i;
			} else
				i++;
		}
		if (x > 1)
			s.push(x);
		for (int i = 2; i * i <= y;) {
			if (y % i == 0) {
				ss.push(i);
				y /= i;
			} else
				i++;
		}
		if (y > 1)
			ss.push(y);
		while (!s.empty() && !ss.empty()) {
			if (s.top() == ss.top())//如果有相等的最大质因子
				s.pop(), ss.pop();//消掉
			else
				break;
		}
		cout << s.size() + ss.size() << '\n';//因子数量和
	}


	hahahahahaha 0;
}

解析

对于18和108:

  • 1到18的路径是:1(3)->3(3)->9(2)->18,而1到108的路径是1(3)->3(3)->9(3)->27(2)->54(2)->108。
  • 可以发现这两个路径中有重复的路径1(3)->3(3)->9,可以合并。
  • 所以如果把这个路径分开,那么答案就多了4条边,也就是上文中消掉两次3,而又因为题目中说父结点是除k以外k的最大的因数,所以要消掉最大的质因子。
posted @ 2025-07-13 10:29  王泽林  阅读(44)  评论(0)    收藏  举报