bruteforce
간단한 길이 가장 쉬운 길이라고, 이래저래 고민해보았지만 결국 bruteforce가 가장 간단한 방법이었다. 문자열을 나누는 기준점을 i
j
기준으로 하여 이중 for문을 돌려 새로운 문자열을 만들어낼 수 있다. 알파벳 순서로 앞서는지는 <
comparison operator을 통해서 간단하게 확인할 수 있다.
다만 주의할 점은 reverse(begin, end)
함수는 begin ‘다음’ 위치부터 end ‘포함’ 위치까지 index을 뒤집는다. 즉, $ begin < index <= end $ 가 되는 셈! 따라서 이를 고려해서 index에 1을 더해주어 맞춰주어야 한다.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
string word, temp, ans="";
string l1, l2, l3;
cin >> word;
for (int i=0; i<word.size(); i++){
ans += 'z';
}
for (int i=0; i<word.size()-2; i++){
for (int j=i+1; j<word.size()-1; j++){
temp = word;
reverse(temp.begin(), temp.begin()+i+1);
reverse(temp.begin()+i+1, temp.begin()+j+1);
reverse(temp.begin()+j+1, temp.end());
if (ans > temp){
ans = temp;
}
}
}
cout << ans << endl;
return 0;
}
여담 - 틀린 풀이
처음 접근은 word의 각 자리를 ASCII로 바꾸어 vec에 저장한 뒤에, 최솟값 2개를 뽑아서 그것을 기준으로 reverse
시켰다. 얼핏 보기에는 큰 문제가 없어 보이지만, abbc
혹은 abbaabba
와 같이 같은 알파벳이 여러 번 등장하는 경우, 최적의 답을 도출하지 못한다.
- 틀린 풀이니 주의!!
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
int prev=0, curr=0;
string word;
vector<int> vec;
cin >> word;
for (char& c: word){
vec.push_back(c-'0');
}
for (int i=0; i<2; i++){
curr = min_element(vec.begin()+prev, vec.end()) - vec.begin() + 1;
reverse(word.begin()+prev, word.begin()+curr);
prev = curr;
}
reverse(word.begin()+prev, word.end());
cout << word;
return 0;
}