菜鸡如我,只能参加一下下beginner级别的比赛了。
感觉ABC级别的比赛还是比较适合我的,也能锻炼一下思维。
题目原网页:https://atcoder.jp/contests/abc142/tasks/abc142_d?lang=en
本菜鸡的大致翻译:
输入两个正整数A, B, 我们可以得到他们的公约数所构成的集合。
我们希望可以从这个集合中挑选出尽量多的数,但是要保证其中任意两个都是互质。
例如输入
12 18
他们的公约数组成的集合是
{1, 2, 3, 6}
我们可以挑选出
{1, 2, 3}
这个集合中的元素两两互质,这个集合有三个元素,因此我们输出
3
题目数据限制:
输入都是正整数,最大可以到1e12。
样例1:
输入
12 18
输出
3
其余例子可以去网页看。
下面给一个本菜鸡的代码。
#include <iostream>
#include <algorithm>
#include <unordered_set>
using namespace std;
unordered_set<int> ans;
void get_res(long long n){
if (n == 1){
return;
}else{
int flag = 0;
for (long long i = 2; i * i <= n; i++){
if(n % i == 0){
ans.insert(i);
flag ++;
n /= i;
break;
}
}
if (flag){
get_res(n);
} else {
ans.insert(n);
}
}
}
int main(){
long long a,b;
cin >> a >> b;
long long m,n;
long long temp;
if(a >= b){
m = a;
n = b;
}else{
m = b;
n = a;
}
while(m % n){
temp = m % n;
m = n;
n = temp;}
if(n!=1){
get_res(n);}
cout << ans.size() +1 << endl;
return 0;
}
大概思路是这样的。
先辗转相除求gcd,然后进行质因子分解,不同的质因子的个数再加上1(因为1也是公约数),就是结果了。
这个思路可以用抽屉原理证明,还是比较简洁的。
代码中get_res的输入是gcd, 会往全局变量ans中添加质因子,因为是个哈希集合,所以自然会去重,最后输出这个集合的大小 + 1就是答案啦。
另外这是我第一次参加比赛。。。
这一题一开始就想出来了,但是没注意1e12,所以一开始一直报错(一开始写的int, 不是long long),罚了很多时。非竞赛玩家在做这些题的时候一定要注意数据范围。。。