洛谷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的最大的因数,所以要消掉最大的质因子。
浙公网安备 33010602011771号