문제 풀이
주어진 문자열을 3개의 문자열로 나눈 다음에 각각의 문자열을 뒤집고, 뒤집은 3개의 문자열을 다시 합치면 된다.
문제는 어떻게 3등분을 하는가이다.
문제에서 문자열을 나눌 때 최소한 문자열의 길이가 1을 보장해야 한다고 명시되어있다.
문제에서 주어진 예시(arrested)를 3등분한다고 한다면? 아래처럼 다양하게 나올 것이다.
a / r / rested
a / rr / ested
a / rre / sted
...
arrest / e / d
하나의 색종이를 2등분으로 만들고 싶다면? 가위로 한 번 자르면 된다.
하나의 색종이를 3등분으로 만들고 싶다면? 가위로 두 번 자르면 된다.
우리는 3등분을 원하므로 총 2번의 경계선만 구하면 된다.
[문자열의 시작 지점 - i - j - 문자열의 끝 지점]
i와 j는 3등분을 하는 경계선이라고 생각해보면 다음과 같이 정리할 수 있다.
(0 ~ i) 까지 부분 문자열 추출
(i ~ j) 까지 부분 문자열 추출
(i+j ~ 끝)까지 부분 문자열 추출
경계선을 구했다.
그런데 i를 어디까지 보면 될까?
문제에서 봤듯이 문자열은 최소 1개의 문자를 포함해야하므로 입력된 문자열 길이의 - 2까지만 돌면 된다.
그러면 j는 어디까지 보면 될까?
만약에 i가 최대 문자열의 길이 - 2 까지 오게 됬다면 j는 문자열의 길이 - i - 1까지만 돌면 된다.
다양한 문자열이 나타났을 때,
사전순으로 가장 앞선 단어를 구하기 위해서는 문자열끼리 비교해서 더 작은 문자열로 갱신하면 된다.
소스 코드
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
string str;
cin >> str;
string ans;
int len = static_cast<int>(str.size());
for(int i = 1; i <= len - 2; i++)
{
for(int j = 1; j <= len - i - 1; j++)
{
string a = str.substr(0,i);
string b = str.substr(i,j);
string c = str.substr(i+j);
reverse(a.begin(), a.end());
reverse(b.begin(), b.end());
reverse(c.begin(), c.end());
string ret = a + b + c;
if(ans == "") ans = ret;
else if(ans > ret) ans = ret;
}
}
cout << ans << endl;
return 0;
}
'Algorithm' 카테고리의 다른 글
[백준 18352] 특정 거리의 도시 찾기 (0) | 2021.11.04 |
---|---|
[백준 10282] 해킹 (0) | 2021.10.31 |
[백준 5670] 휴대폰 자판 (0) | 2021.10.19 |
[백준 4358] 생태학 (0) | 2021.10.19 |
[백준 15903] 카드 합체 놀이 (0) | 2021.10.13 |