次大公约数

辗转相除法找最大公约数,然后用欧拉筛求出以内的质数与是否除尽来找答案

另好像有其他好方法,数论渣渣😪

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define LL long long
#define IN freopen("in.txt", "r", stdin)
#define OUT freopen("out.txt", "w", stdout)
#define scan(x) scanf("%d", &x)
#define f(i, a, b) for (int i = a; i <= b; i++)
#define pn(x) printf("%d", x)
#define lowbit(x) (x & (-x))

int cnt = 0;
void Euler_prime(int n, bool *vis, int *prime)
{
vis[1] = true;
for (int i = 2; i <= n; ++i)
{
if (!vis[i])
prime[cnt++] = i;
for (int j = 0; j < cnt; ++j)
{
if (i * prime[j] > n) //判断是否越界
break;
vis[i * prime[j]] = true; //筛数
if (i % prime[j] == 0)
break;
}
}
}

int main()
{
int n, x, min, max;
scan(n);
scan(x);
min = n < x ? n : x;
max = n > x ? n : x;
while (max % min)
{
int temp = max % min;
max = min;
min = temp;
}
if (min == 1)
{
printf("-1");
return 0;
}
int *prime = (int *)malloc(sizeof(int) * (min / 2));
bool *vis = (bool *)malloc(sizeof(bool) * (min + 1));
memset(vis, 0, sizeof(bool) * (min + 1));
Euler_prime(min, vis, prime);
f(i, 0, cnt - 1)
{
if ((min / prime[i]) * prime[i] == min)
{
pn(min / prime[i]);
return 0;
}
}
printf("1");
return 0;
}