728x90
소수 경로
https://www.acmicpc.net/problem/1963
<코드>
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 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | #include <stdio.h> #include <vector> #include <queue> using namespace std; int primGroup[10001]; struct couple{ int a; int b; }; couple make_couple(int a, int b){ couple temp; temp.a = a; temp.b = b; return temp; } int main(void){ int a[10001] = {}; int primGroup[10001] = {}; vector<int> prim; for (int i = 2; i <= 10000; i++) { if (a[i] == 0) { int count = 1; prim.push_back(i); a[i*count] = 1; while (i*count <= 10000){ a[i*count++] = 1; } } else continue; } for (int i = 0; i < prim.size(); i++) primGroup[prim[i]] = 1; int testcase; scanf("%d", &testcase); while (testcase--){ int first, end; int result = -1; int visit[10001] = {}; queue<couple> que; // 처음은 int 는 숫자 다음 int는 count; scanf("%d %d", &first, &end); que.push(make_couple(first,0)); visit[first] = 1; pair<int, int> a; while (!que.empty()){ couple temp = que.front(); int Digit[4]; int tempNum = temp.a; int d[4] = { 1000, 100, 10, 1 }; if (temp.a == end){ result = temp.b; break; } for (int i = 0; i < 4; i++){ Digit[i] = tempNum / d[i]; tempNum = tempNum%d[i]; } que.pop(); for (int i = 0; i < 4; i++){ tempNum = temp.a - Digit[i] * d[i]; for (int j = 0; j <= 9; j++) { int compareNum = tempNum + d[i] * j; if (i == 0 && j == 0) continue; if (primGroup[compareNum] == 1 && visit[compareNum] == 0){ visit[compareNum] = 1; que.push(make_couple(compareNum, temp.b + 1)); } } } } if (result == -1) printf("Impossible\n"); else printf("%d\n", result); } return 0; } | cs |
<문제 푼 요령>
1. 먼저 에라토스 체를 이용하여서 소수만 구하게 된다.
2.구한 소수들을 primGroup으로 따로 체크를 해서 나중에 index만으로 소수인지 아닌지를 바로 알 수 있게 만들어 놨다.
3. 처음 네 자리 수에서 두번째 네 자리 수를 바꾸는 과정을 거칠때도 그 숫자들은 소수여야하는 전재 조건이 매우 중요하다.
4. 처음 수에서 각자리수별로 바꿔가면서 새로운 숫자를 만들어보는데 여기서 이 새로운 숫자가 소수인지 판별을 하고 이전에 이 숫자가 나왔는지 판별하여서 새롭게 나온 숫자로 부합하면 큐에 이 숫자를 집어넣는다.
5. 이렇게 큐에 집어넣고 빼고를 반복하는 BFS 탐색 방법을 이용하여 보면 두 소수를 변환에 필요한 최소 회수를 출력할 수 있고 만약 불가능한 경우는 result가 한번도 갱신이 되지 않기 때문에 판별할 수 있다.
728x90
'Algorithm > BFS(너비우선 탐색)' 카테고리의 다른 글
[백준][1325번][BFS] 효율적인 해킹 (2) | 2016.04.08 |
---|
댓글