백준 1039번 교환
< 백준 1039번 교환 - 마포 코딩박 >
사용한 알고리즘: BFS
N자리 숫자가 주어지고, 이 숫자의 i번째와 j번째를 바꾸는 것을 K번 했을때 나올 수 있는 최대 숫자를 구하는 문제였습니다.
문제풀이는 다음과 같습니다.
(1) (코드: 63~64)
주어진 숫자가 1자리 수이거나, 2자리수이면서 뒷자리가 0인 경우 조건에 의해 바꾸는 행동을 할 수 없습니다. 이때 -1 을 출력합니다.
(2) (코드: 8~15)
string으로 받은 숫자를 int로 변환해주는 함수를 하나 만들어줍니다.
(3) (코드: 17~57)
x번 바꾼 숫자를 저장할 queue를 만듭니다.
처음에는 0번 바뀐 (처음 입력받은) 숫자를 queue에 넣어줍니다.
queue에 들어있는 x번 바뀐 모든 수를 꺼내 각 수의 모든 가능한 i<->j 바꾸기를 해준 후 다시 queue에 저장합니다.
( 이후 queue에는 x+1번 바뀐 모든 수가 들어있게됩니다.)
(4) (코드: Visit, 27줄)
과정 (3)을 진행하며, set<string> 을 만들어 중복해서 저장하는 것을 피합니다.
(5) (코드: 43,44)
K번 바뀐 수 중 최대를 답으로 출력합니다.
사용한 알고리즘: BFS
N자리 숫자가 주어지고, 이 숫자의 i번째와 j번째를 바꾸는 것을 K번 했을때 나올 수 있는 최대 숫자를 구하는 문제였습니다.
문제풀이는 다음과 같습니다.
(1) (코드: 63~64)
주어진 숫자가 1자리 수이거나, 2자리수이면서 뒷자리가 0인 경우 조건에 의해 바꾸는 행동을 할 수 없습니다. 이때 -1 을 출력합니다.
(2) (코드: 8~15)
string으로 받은 숫자를 int로 변환해주는 함수를 하나 만들어줍니다.
(3) (코드: 17~57)
x번 바꾼 숫자를 저장할 queue를 만듭니다.
처음에는 0번 바뀐 (처음 입력받은) 숫자를 queue에 넣어줍니다.
queue에 들어있는 x번 바뀐 모든 수를 꺼내 각 수의 모든 가능한 i<->j 바꾸기를 해준 후 다시 queue에 저장합니다.
( 이후 queue에는 x+1번 바뀐 모든 수가 들어있게됩니다.)
(4) (코드: Visit, 27줄)
과정 (3)을 진행하며, set<string> 을 만들어 중복해서 저장하는 것을 피합니다.
(5) (코드: 43,44)
K번 바뀐 수 중 최대를 답으로 출력합니다.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <bits/stdc++.h> | |
using namespace std; | |
string S; | |
int K, M; | |
vector<int> Answer; | |
// 문자열 S 를 숫자로 바꿈 | |
int Calcul(string S){ | |
int Sum = 0; | |
for (int i = 0; i < S.length(); i++){ | |
Sum *= 10; | |
Sum += (S[i] - '0'); | |
} | |
return Sum; | |
} | |
void BFS(string S){ | |
queue<string> Q; | |
Q.push(S); | |
// 바꾼 횟수 | |
int cnt = 0; | |
// 찾은 수 중 최대 | |
int ans = 0; | |
while(!Q.empty() && cnt < K){ | |
int Qs = Q.size(); | |
// 똑같은 수 바꾸기 반복 방지 (메모리 초과 방지) | |
set<string> Visit; | |
// cnt=i 일때 i번 바뀐수들이 Q에 저장되어 있다. | |
// 모든 i번 바뀐 수들을 한번씩 더 바꿔본다. | |
for (int q = 0; q < Qs; q++){ | |
string now = Q.front(); | |
Q.pop(); | |
// 숫자 바꿔보기 | |
for (int i = 0; i < M - 1; i++){ | |
for (int j = i + 1; j < M; j++){ | |
// 0 으로 숫자가 시작하면 안된다. | |
if (i == 0 && now[j] == '0') continue; | |
swap(now[i], now[j]); | |
if(!Visit.count(now)){ | |
// K번 바꾼경우 최대 수 찾기 | |
if(cnt == K-1) | |
ans = max(ans,Calcul(now)); | |
Q.push(now); | |
Visit.insert(now); | |
} | |
swap(now[i], now[j]); | |
} | |
} | |
} | |
cnt++; | |
} | |
if(cnt!=K) cout << -1 << endl; | |
else cout << ans << endl; | |
} | |
int main(){ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL); | |
cin >> S >> K; | |
M = S.length(); | |
// 주어진 수가 1자리 수일때 or 2자리이고 뒷자리 0 일때 | |
if(M == 1 || (M == 2 && Calcul(S)%10==0)) | |
cout << "-1" << endl; | |
else | |
BFS(S); | |
return 0; | |
} |
댓글
댓글 쓰기
긴 글 읽어주셔서 감사합니다.
궁금한게 있으시다면 댓글 달아주세요!