문제 출처
1. 문제설명
- 빨간색 볼과 파란색 볼이 일직선상에 섞여 놓여 있을 때, 볼을 옮겨서 같은 색 볼끼리 인접하게 놓이도록 하려고 한다.
- 한번 어떤 색의 공을 옮기면, 같은 색의 공만 옮길 수 있다.
- 같은 색끼리 모을 때 최소 이동횟수를 구하라.
2. 알고리즘 설계
- 빨간공과 파란공 두 종류의 공이 있다.
- 같은 색끼리 모으려면 어떤 방법이 있을까?
- 어떤 색의 공을 왼쪽으로만 옮기는 방법
- 오른쪽으로만 옮기는 방법
- 좌/우를 병행하지 않는다.
- 공이 두개고, 인접해야 하기 때문에 방향을 바꿀 필요가 없다.
3. 로직
- 왼쪽으로 어떤 색의 공을 옮기는 방법
- 오른쪽으로 어떤 색의 공을 옮기는 방법
- 각각의 경우를 모두 구해 4가지 경우 중 최소값을 그리디하게 취하면 된다.
- 알고리즘
- 빨간 공을 만나면,
red_temp
를 1로 설정하고, 빨간 공의 카운팅은 blue_temp
를 더한다.
- 파란 공을 만나면,
blue_temp
를 1로 설정하고, 파란 공의 카운팅은 red_temp
를 더한다.
- 위와 같이 구현하면 각 방향에 대해 하나의 for-loop로 처리할 수 있다.
4. 전체 코드
#include <bits/stdc++.h>
using namespace std;
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(NULL);
int n, r_tmp = 0, r_cnt = 0, b_tmp = 0, b_cnt = 0, ans;
string str;
cin >> n >> str;
for (int i = 0; i < str.size(); i++) {
if (str[i] == 'R') {
r_tmp = 1;
r_cnt += b_tmp;
}
else {
b_tmp = 1;
b_cnt += r_tmp;
}
}
ans = min(r_cnt, b_cnt);
r_tmp = 0, r_cnt = 0, b_tmp = 0, b_cnt = 0;
for (int i = str.size() - 1; i >= 0; i--) {
if (str[i] == 'R') {
r_tmp = 1;
r_cnt += b_tmp;
}
else {
b_tmp = 1;
b_cnt += r_tmp;
}
}
ans = min(ans, min(r_cnt, b_cnt));
cout << ans;
return 0;
}