본문 바로가기
백준

[백준 2916] 자와 각도기, C++

by 황인태(intaehwang) 2020. 4. 27.
반응형

https://www.acmicpc.net/problem/2916

 

2916번: 자와 각도기

문제 창영이는 방 청소를 하다가 자와 각도기를 발견했다. 다음날 창영이는 학교에 자와 각도기를 들고 갔고, 현우와 "작도 대결"을 하려고 한다. 창영이는 각도기와 자를 이용해서 만들 수 있는 각을 알고 있고, 두 각을 합하거나 빼서 새로운 각을 만드는 방법을 알고 있다. 현우가 어떤 각도를 외치면, 창영이는 자와 각도기를 이용해서 현우가 외친 각도를 작도해야 한다. 작도할 때는 새로운 각을 이용해서 또다른 새로운 각을 만드는 것도 가능하다. 현우가 외치는

www.acmicpc.net

본 문제는 주어진 n개의 각을 이용해 합하거나 빼서 새로운 각을 만든다. 또한 새로운 각을 이용해서 또 다른 새로운 각을 만드는 것도 가능하다. 주어진 k개의 각을 만들 수 있으면 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
76
77
78
79
#include <cstdio>
#include <vector>
 
using namespace std;
 
bool chk[730];
 
int main() {
    int n, m;
    scanf("%d %d"&n, &m);
 
    // 1. 주어진 n개의 각도로 만들수 있는 모든 각도 만들기
    vector<int> v(n);
 
    // 1.을 통해 만들어진 각도 중 u가 있는지 확인
    vector<int> u(m);
 
    for (int i = 0; i < n; i++) {
        scanf("%d"&v[i]);
        chk[v[i]] = true;
    }
 
    for (int i = 0; i < m; i++) {
        scanf("%d"&u[i]);
    }
 
    // 두 각을 더하여 새로운 각 만들기
    while (true) {
        bool flag = false;
        for (int i = 0; i < v.size(); i++) {
            for (int j = 0; j < v.size(); j++) {
                int tmp = v[i]+v[j];
 
                // 모든 각도는 360보다 작다.
                // 따라서 400도 일 경우 40도로 변경해야 한다.
                if (tmp >= 360) tmp -= 360;
                if (!chk[tmp]) {
                    flag = true;
                    chk[tmp] = true;
 
                    // 새로운 각을 추가
                    v.push_back(tmp);
                }
            }
        }
        if (!flag) break;
    }
 
    // 두 각을 빼서 새로운 각 만들기
    while (true) {
        bool flag = false;
        for (int i = 0; i < v.size(); i++) {
            for (int j = 0; j < v.size(); j++) {
                int tmp = v[i]-v[j];
 
                // 음의 각은 양의 각으로 변경한다.
                if (tmp < 0) tmp = -tmp;
                
                // 두 각도의 합이 360을 넘는 경우가 없기 때문에
                // 두 각도의 차가 360을 넘을 수 없다.
                // if (tmp >= 360) tmp -= 360;
 
                if (!chk[tmp]) {
                    flag = true;
                    chk[tmp] = true;
 
                    // 새로운 각을 추가
                    v.push_back(tmp);
                }
            }
        }
        if (!flag) break;
    }
 
    for (int i = 0; i < m; i++) {
        if (!chk[u[i]]) printf("NO\n");
        else printf("YES\n");
    }
}
cs
반응형
Buy me a coffeeBuy me a coffee

댓글