[백준] 14395번 4연산 (C++)

2025. 8. 30. 14:33·Algorithm
728x90

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

 

 

이 문제는 정수 s와 t가 주어졌을때 4가지 연산을 최소로 사용하여 정수 s를 t로 바꾸는 연산의 개수를 출력하는 문제이다.

 

그렇다면 s에서 t의 최소 연산을 구하는 방법을 알아야하는데 

 

처음엔 그리디하게 접근을 해서 계속 s와 t의 차이가 클 경우 곱셈을 우선적으로 사용해야하나 생각을 해보았다.

 

결국 연산을 한 s를 같은 숫자를 더하고 곱하거나 빼거나 해야하기 때문에 값이 정확하게 t로 바꾸는 것은 그리디하게 풀 수 없다고 생각하였다.

 

그렇다면 할 수 있는 방법이 모든 경우의 방법을 구하는 것이다 즉 정수 s에서 4가지 연산을 사용한 값들에 대해서 

다시 4가지 연산을 사용하여 t로 만들 수 있는지 확인한다.

 

이때 다시 같은 값을 다시 연산을 하게 되는 경우가 생기는데 이것을 방문처리를 하기 위해서 집합(set)의 자료구조를 사용하여 최적화 하였다.

 

 

 

정답코드

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
#define endl "\n"
#define MAX 1e9

struct coordinate {
    int x;
    int y;
    int r;
};

struct nutrition {
    int p;
    int f;
    int s;
    int v;
    int cost;
};

int dx[] = {0 ,0, -1, 0, 1, 1, -1, -1, 1};
int dy[] = {0, -1, 0, 1, 0, -1, 1, -1, 1};
ll s, t;
set<ll> st;

bool check(int a) {
    if(a < 0 || a > MAX) return false;

    if(st.find(a) != st.end()) {
        return false;
    }
    return true;
}

void bfs() {
    queue<tuple<ll, string>> q;
    q.push({s, ""});
    st.insert(s);

    while(!q.empty()) {
        ll x = get<0>(q.front());
        string sol = get<1>(q.front());
        q.pop();

        if(x == t) {
            cout << sol;
            exit(0);
        }

        for(int i = 0; i < 4; i++) {
            if(i == 0) {
                ll stand = x * x;
                if(check(stand)) {
                    q.push({stand, sol + '*'});
                    st.insert(stand);
                }
            }
            else if(i == 1) {
                ll stand = x + x;
                if(check(stand)) {
                    q.push({stand, sol + '+'});
                    st.insert(stand);
                }
            }
            else if(i == 2) {
                ll stand = x - x;
                if(check(stand)) {
                    q.push({stand, sol + '-'});
                    st.insert(stand);
                }
            }
            else {
                ll stand = x / x;
                if(check(stand)) {
                    q.push({stand, sol + '/'});
                    st.insert(stand);
                }
            }
        }
    }
}

void solve() {
    if(s == t) {
        cout << 0;
        return;
    }

    bfs();

    cout << -1;
}

void input() {
    cin >> s >> t;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    input();
    solve();
}

 

먼저 bfs 함수 내부를 살펴보자

void bfs() {
    queue<tuple<ll, string>> q;
    q.push({s, ""});
    st.insert(s);

    while(!q.empty()) {
        ll x = get<0>(q.front());
        string sol = get<1>(q.front());
        q.pop();

        if(x == t) {
            cout << sol;
            exit(0);
        }

        for(int i = 0; i < 4; i++) {
            if(i == 0) {
                ll stand = x * x;
                if(check(stand)) {
                    q.push({stand, sol + '*'});
                    st.insert(stand);
                }
            }
            else if(i == 1) {
                ll stand = x + x;
                if(check(stand)) {
                    q.push({stand, sol + '+'});
                    st.insert(stand);
                }
            }
            else if(i == 2) {
                ll stand = x - x;
                if(check(stand)) {
                    q.push({stand, sol + '-'});
                    st.insert(stand);
                }
            }
            else {
                ll stand = x / x;
                if(check(stand)) {
                    q.push({stand, sol + '/'});
                    st.insert(stand);
                }
            }
        }
    }
}

 

처음 s노드를 삽입하여 4가지 연산을 사용하여 check함수에 인자로 넘겨준다. check 함수는 

set에 연산을 한 값이 있는지 없는지 확인하는 로직이다. 만약 없으면 아직 연산을 하지 않은것이기 때문에

큐에 다시 넣어주며 set에 넣어준다.

 

이후 x의 값이 t와 같은 경우 연산의 순서를 출력해주며 못만들경우 -1을 출력한다.

 

728x90
저작자표시 (새창열림)

'Algorithm' 카테고리의 다른 글

[백준] 11502번 세 개의 소수 문제 (C++)  (0) 2025.09.01
[백준] 23326번 홍익 투어리스트 (C++)  (0) 2025.08.31
[백준] 13265번 색칠하기 (C++)  (0) 2025.08.29
[백준] 14620번 꽃길 (C++)  (0) 2025.08.28
[백준] 25381번 ABBC (C++)  (0) 2025.08.27
'Algorithm' 카테고리의 다른 글
  • [백준] 11502번 세 개의 소수 문제 (C++)
  • [백준] 23326번 홍익 투어리스트 (C++)
  • [백준] 13265번 색칠하기 (C++)
  • [백준] 14620번 꽃길 (C++)
쿨쿨.
쿨쿨.
  • 쿨쿨.
    All of the life
    쿨쿨.
  • 전체
    오늘
    어제
    • 분류 전체보기 (285) N
      • Programming (52) N
        • C, C++ (18)
        • Python (6)
        • Java (1)
        • HTML,CSS,JS (3)
        • SQL(DB) (13)
        • SpringBoot (8) N
        • Android (2)
        • CI,CD (1)
      • Algorithm (173)
        • Review (4)
      • Security (14)
        • WebHacking (3)
        • Websecurity (11)
      • OS (19)
        • Linux (12)
        • Mac os (2)
      • 머신러닝 (1)
      • CS(Computer Science) (12)
        • 컴퓨터 네트워크 (3)
        • 컴퓨터 구조 (1)
        • 인공지능 (8)
      • Docker (2) N
      • Dev Book Review (3)
        • Clean Code (1)
        • Effective Java (0)
        • Real MySQL (2)
      • SWM (1)
      • Review (6)
      • AWS (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    트리
    재귀
    다이나믹 프로그래밍
    다익스트라
    정렬
    백트래킹
    구현
    c언어
    누적합
    우선순위큐
    WebSecurity
    우선순위 큐
    Bandit
    DFS
    코딩
    DP
    브루트포스
    깊이우선탐색
    시뮬레이션
    Leviathan
    BFS
    백준
    linux
    그리디
    이분탐색
    비트마스킹
    그래프 이론
    에라토스테네스의 체
    wargame
    투포인터
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.6
쿨쿨.
[백준] 14395번 4연산 (C++)
상단으로

티스토리툴바