happy318
팽도리블로그
happy318
전체 방문자
오늘
어제
  • 전체글 (252)
    • 공부 (5)
      • Algorithm 정리 (0)
      • 논문리뷰 (1)
      • C++ (2)
      • Python (2)
      • Java (0)
      • Back-end (0)
      • Front-end (0)
      • Embedded (0)
    • 코딩테스트 (218)
      • Python 문제풀이 (100)
      • C++ 문제풀이 (108)
      • Python template (9)
      • C++ template (1)
    • 일상 (20)
      • 맛집 (13)
      • 쇼핑 (5)
      • 아무 일상 (2)
    • 게임 (9)
      • 메이플스토리 (9)

최근 글

인기 글

hELLO · Designed By 정상우.
happy318

팽도리블로그

코딩테스트/C++ 문제풀이

[백준] 소수 경로

2022. 11. 24. 00:38

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

 

1963번: 소수 경로

소수를 유난히도 좋아하는 창영이는 게임 아이디 비밀번호를 4자리 ‘소수’로 정해놓았다. 어느 날 창영이는 친한 친구와 대화를 나누었는데: “이제 슬슬 비번 바꿀 때도 됐잖아” “응 지금

www.acmicpc.net

BFS를 이용하는 문제입니다.

 

우선 문제부터 간단하게 요약하면, 

1033 -> 8179 처럼 소수에서 소수로 변환이 일어나야 하는데, 중간에 변경되는 값들은 

1033 1733 3733 3739 3779 8779 8179

처럼 4자리중 1자리 숫자만 달라져야 하고, 각각 또한 소수여야 하고, 1000이상의 4자리 수여야합니다. 

 

이 때, 최소 횟수만에 변환이 일어난다고 하면, 얼마의 변환이 필요한지 출력해야 하고, 만약 불가능하다면, Impossible을 출력해야 합니다.

 

<Solution>

알고리즘은 간단합니다. 

1. queue에 첫번째 숫자를 넣고 방문 표시를 한다.
2. 큐가 빌 때 까지 매번 queue를 pop하고, 한자리 숫자만 바꾼 수에 대해
2-1. 도달해야 하는 수라면 return
2-2. 소수인지 판단하고, 이미 방문했는지 판단하고, 1000보다 작아지지 않는지 판단해서
2-3. 방문표시를 하고 변경한 숫자를 queue에 넣어주어야 한다.

 

이 과정을 실제로 구현하면 아래와 같습니다. 

주의 해야하는 점은, 한자리 숫자를 바꾸는 과정과, 숫자를 바꾸다 1000보다 작아지는 경우 등을 주의해서 생각해서 구현하여야 합니다.

#include <iostream>
#include <cmath>
#include <queue>
#include <cstring>
using namespace std;
 
int S, E;//출발 정류장 번호, 도착 정류장 번호

void InputData(){
    cin >> S >> E;
}
bool is_prime(int k){
    int min = 2;
    int max = int(sqrt(k)) +1;
 
    if(k == 2) return true;
 
    for(int i = min; i<=max; i++){
        if(k%i == 0) return false;
    }
    return true;
 
}
 
struct k{
    int num, times;
};
 
int solution(){
    char visited[10000];
    memset(visited, 0, sizeof(visited));
    queue <k> my_q;
    k init = {S, 0};
    if(S == E) return 0;
    my_q.push(init);
    visited[init.num] = '1';

    while(!my_q.empty()){
        k e = my_q.front(); my_q.pop();
 
        for(int j = 1; j<=4; j++){
            int p = pow(10,j);
            for(int i = 1; i<=9; i++){
                int new_num=0;
                new_num+=e.num/p * p;
                new_num+=((e.num%p) + i*p/10)% p;
 
                if(new_num < 1000) continue;
 
                if(visited[new_num] == '1') continue;
                if(new_num == E) return e.times+1;
                if(is_prime(new_num)){
                    visited[new_num] = '1';                    
                    my_q.push((k){new_num, e.times+1});
                }
            }
        }
 
    }
    return -1;
}
 
int main(){
    int ans = -1;
    int T;
    cin >> T;
    for(int i = 0; i<T; i++){
        InputData();
 
        ans = solution();
        if(ans == -1) {
            cout << "Impossible" << endl;
        }
        else {
            cout << ans << endl;
        }
    }

    return 0;
}
반응형

'코딩테스트 > C++ 문제풀이' 카테고리의 다른 글

[백준] 폭탄제조  (0) 2022.11.24
[정올] 저글링 방사능 오염  (0) 2022.11.24
[백준] 탈출  (0) 2022.11.23
[백준] 버스 갈아타기  (1) 2022.11.23
[백준] 문자열 폭발  (0) 2022.11.23
    '코딩테스트/C++ 문제풀이' 카테고리의 다른 글
    • [백준] 폭탄제조
    • [정올] 저글링 방사능 오염
    • [백준] 탈출
    • [백준] 버스 갈아타기
    happy318
    happy318

    티스토리툴바