컴퓨터 공학 기초/알고리즘 (브루트포스)
백준 2529 (부등호)
JongSeok_12
2020. 8. 17. 13:32
https://www.acmicpc.net/problem/2529
2529번: 부등호
여러분은 제시된 부등호 관계를 만족하는 k+1 자리의 최대, 최소 정수를 첫째 줄과 둘째 줄에 각각 출력해야 한다. 단 아래 예(1)과 같이 첫 자리가 0인 경우도 정수에 포함되어야 한다. 모든 입력�
www.acmicpc.net
해당 문제는 0 ~ 9 까지 의 숫자들의 순열(중복 X)을 사용하여 주어진 부등호의 경우가 일치할 때 순열에 사용된 숫자를 비교하여 최대값과 최소값을 비교하는 문제이다.
풀이 :
DFS를 사용한 재귀를 이용하여 문제풀이
1. 규칙 찾기
가장 첫번째 숫자를 제외한 나머지 숫자는 항상 부등호 뒤에 위치한다. 따라서 1 중 for 문을 사용하여 가장 첫 번째 숫자를 넣어준 뒤 재귀함수를 수행시키며 부등호 -> 숫자 순으로 push 시켜주면 된다.
2. 재귀함수로 탐색할 때 부등호와 숫자를 push 하는 과정에서 해당 부등호와 숫자를 넣었을 때 식이 참으로 성립되는지 확인하며 참으로 성립할 때에만 재귀를 진행하며 최적화 시켜준다.
#include <iostream>
#include <vector>
#include <cstring>
#include <algorithm>
#include <string>
#include <queue>
using namespace std;
int k;
vector<char> opList;
vector<char> resList;
int used[11];
long long minn = 999999999999;
long long maxx = -999999999999;
string minStr;
string maxStr;
string resComp(vector<char> nList){
string str;
int n = nList.size();
for (int i = 0; i <= n - 2; i += 2){
if (nList[i + 1] == '>'){
if (nList[i] < nList[i + 2]) { str = ""; return str; };
}
else{
if (nList[i] > nList[i + 2]) { str = ""; return str; };
}
str.push_back(nList[i]);
}
str.push_back(nList[n - 1]);
return str;
}
long long changNum(string str){
int n = str.length();
long long sum = 0;
for (int i = 0; i < n; ++i){
sum = sum * 10 + (str[i] - 48);
}
return sum;
}
void dfs(int level){
if (level == k){
string tmp = resComp(resList);
long long sum = changNum(tmp);
if (maxx < sum){
maxx = sum;
maxStr = tmp;
}
if (minn > sum){
minn = sum;
minStr = tmp;
}
return;
}
for (int i = 0; i <= 9; ++i){
if (used[i] == 1) continue;
int n = resList.size();
// 부등호를 넣었을 때 해당 식이 참일경우에만 재귀 수행
if (opList[level] == '<'){
if (resList[n - 1] < (i + 48)){
used[i] = 1;
resList.push_back(opList[level]);
resList.push_back(i + 48);
dfs(level + 1);
used[i] = 0;
resList.pop_back();
resList.pop_back();
}
}
else{
if (resList[n - 1] > (i + 48)){
used[i] = 1;
resList.push_back(opList[level]);
resList.push_back(i + 48);
dfs(level + 1);
used[i] = 0;
resList.pop_back();
resList.pop_back();
}
}
}
}
int main(){
//freopen_s(new FILE*, "tes.text", "r", stdin);
cin >> k;
for (int i = 0; i < k; ++i){
char tmp;
cin >> tmp;
opList.push_back(tmp);
}
// resList 의 가장 첫번째 숫자 push 후 재귀 수행
for (int i = 0; i <= 9; ++i){
used[i] = 1;
resList.push_back(i + 48);
dfs(0);
used[i] = 0;
resList.pop_back();
}
cout << maxStr << endl;
cout << minStr << endl;
}