본문 바로가기
백준

[백준 1963] 소수 경로

by 황인태(intaehwang) 2020. 2. 26.
반응형

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

 

1963번: 소수 경로

문제 소수를 유난히도 좋아하는 창영이는 게임 아이디 비밀번호를 4자리 ‘소수’로 정해놓았다. 어느 날 창영이는 친한 친구와 대화를 나누었는데: “이제 슬슬 비번 바꿀 때도 됐잖아” “응 지금은 1033으로 해놨는데... 다음 소수를 무엇으로 할지 고민중이야" “그럼 8179로 해” “흠... 생각 좀 해볼게. 이 게임은 좀 이상해서 비밀번호를 한 번에 한 자리 밖에 못 바꾼단 말이야. 예를 들어 내가 첫 자리만 바꾸면 8033이 되니까 소수가 아니잖아.

www.acmicpc.net

 본 문제는 2006 NWERC G번 문제로 비밀번호를 4자리 소수로 한다. 만약 비밀번호를 변경하려고 하면 다음과 같은 과정이 필요하다.

  1. 비밀번호는 반드시 4자리 소수
  2. 비밀번호는 한 번에 한 자리 밖에 못 바꾼다.
  3. 예) 현재 비밀번호가 1033일 때 8179로 변경하려면
    • 1033 1733 3733 3739 8779 8179의 과정이 필요하다.

문제 해결 과정은 다음과 같다.

  1. 비밀번호 4자리 중 천의 자리부터 0 ~ 9의 숫자로 한 번 바꾼다.
  2. 바꾼 숫자가 4자리 소수, 그리고 이전에 바꾼 비밀번호인지 확인한다.
  3. 2번 과정이 맞다면 방법을 1 증가한다.
  4. 비밀번호를 변경하는데 최소 회수를 출력해야 하므로 BFS로 구현하였다.

< 1. 에라토스테네스의 체 사용>

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
#include <cstdio>
#include <queue>
#include <string>
#include <cstring>
 
using namespace std;
 
bool chk[10000];
bool prime[10000];
 
bool is_right(int x) {
    if (x > 1000 && x < 10000return true;
    else return false;
}
 
int main() {
    int t;
    scanf("%d"&t);
    for (int i = 2; i <= 9999; i++) {
        if (!prime[i]) {
            for (int j = i*i; j <= 9999; j += i) {
                prime[j] = true;
            }
        }
    }
    while (t--) {
        int start, end;
        scanf("%d %d"&start, &end);
        queue<pair<intint>> q;
        memset(chk, falsesizeof(chk));
        chk[start] = true;
        q.push(make_pair(start, 0));
        int ans = 0;
        while (!q.empty()) {
            int now = q.front().first;
            int cnt = q.front().second;
            q.pop();
            if (now == end) ans = cnt;
            for (int i = 0; i < 4; i++) {
                string tmp = to_string(now);
                for (int j = 0; j <= 9; j++) {
                    tmp[i] = j + '0';
                    int next = stoi(tmp);
                    if (is_right(next) && !prime[next] && !chk[next]) {
                        chk[next] = true;
                        q.push(make_pair(next, cnt+1));
                    }
                }
            }
        }
        if (chk[end]) printf("%d\n", ans);
        else printf("Impossible\n");
    }
}
cs

 

< 2. 숫자를 변경할 때마다 소수인지 확인>

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
#include <cstdio>
#include <queue>
#include <string>
#include <cstring>
 
using namespace std;
 
bool chk[10000];
 
bool is_prime(int x) {
    if (x < 2return false;
    for (int i = 2; i*<= x; i++) {
        if (x % i == 0return false;
    }
    return true;
}
 
bool is_right(int x) {
    if (x > 1000 && x < 10000return true;
    else return false;
}
 
int main() {
    int t;
    scanf("%d"&t);
    while (t--) {
        int start, end;
        scanf("%d %d"&start, &end);
        queue<pair<intint>> q;
        memset(chk, falsesizeof(chk));
        chk[start] = true;
        q.push(make_pair(start, 0));
        int ans = 0;
        while (!q.empty()) {
            int now = q.front().first;
            int cnt = q.front().second;
            q.pop();
            if (now == end) ans = cnt;
            for (int i = 0; i < 4; i++) {
                string tmp = to_string(now);
                for (int j = 0; j <= 9; j++) {
                    tmp[i] = j + '0';
                    int next = stoi(tmp);
                    if (is_right(next) && is_prime(next) && !chk[next]) {
                        chk[next] = true;
                        q.push(make_pair(next, cnt+1));
                    }
                }
            }
        }
        if (chk[end]) printf("%d\n", ans);
        else printf("Impossible\n");
    }
}
cs

반응형

'백준' 카테고리의 다른 글

[백준 1038] 감소하는 수, C++  (0) 2020.03.02
[백준 15684] 사다리 조작, C++  (0) 2020.03.02
[백준 11559] Puyo Puyo, C++  (0) 2020.02.25
[백준 2573] 빙산, C++  (0) 2020.02.25
[백준 10868] 최솟값, C++  (0) 2020.02.21
Buy me a coffeeBuy me a coffee

댓글