Problem D 풀이 (C++)

문제 링크 : https://codeforces.com/contest/1538/problem/D

1보다 큰 숫자는 무조건 임의의 숫자로 나누어 1로 만들 수 있다.

소인수분해를 통해 숫자 a를 소수의 곱으로 나타내면

소수1 x 소수1 x 소수1 x ... x 소수2 x 소수2 x ...  이런 형태로 나타낼 수 있다.

a를 나눌 수 있는 수는 이 소수들의 조합의 곱으로 만들 수 있는 수이다.

예를 들면,

소수1 x 소수1 x 소수2 x 소수3 으로 구성되어 있는 수라면

소수1 x 소수2의 숫자로 나누었을 때 나머지가 0이고 몫이 소수1 x 소수3이 된다.

이런 방식이라면 임의의 숫자를 1보다 큰 수로 나눌 수 있는 최대 횟수는

소인수분해를 통해 구한 소수들의 개수이다.

이것이 기본 알고리즘이고 예외사항을 보자면

1. a = b = 1 인 경우, 2개 숫자 모두 더 이상 나눌 수 없으므로 "NO" 출력.

2. k = 1인 경우, a나 b 중 한 번만 나누어 둘이 같은 수를 만들어야 하므로

   a % b == 0 || b % a == 0 이고 a != b 라면 "YES" 출력. 아니면 "NO" 출력.



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
66
67
68
69
70
71
72
73
74
75
#include <iostream>
#include <vector>
 
using namespace std;
 
// prime numbers
int primes[40000];
 
int main() {
 
    int t;
    cin >> t;
 
    for (int i = 0; i < 40000; i++)
        primes[i] = 1;
 
    // find prime numbers.
    for (int i = 2; i * i < 40000; i++) {
        if (primes[i] == 1) {
            for (int j = i * i; j < 40000; j += i)
                primes[j] = 0;
        }
    }
 
    while (t--) {
 
        int a, b, k;
        cin >> a >> b >> k;
 
        if (a == 1 && b == 1) {
            cout << "NO" << endl;
            continue;
        }
 
        if (k == 1) {
            if ((a % b == 0 || b % a == 0&& a != b)
                cout << "YES" << endl;
            else
                cout << "NO" << endl;
            continue;
        }
 
        int divNum = 0;
 
        for (int i = 2; i < 40000; i++) {
            if (primes[i] == 1) {
 
                while (a % i == 0) {
                    a /= i;
                    divNum++;
                }
 
                while (b % i == 0) {
                    b /= i;
                    divNum++;
                }
 
                if (a == 1 && b == 1)
                    break;
            }
        }
 
        if (a > 1)
            divNum++;
        if (b > 1)
            divNum++;
 
        if (divNum >= k)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
 
    return 0;
}
cs

댓글