Koder / 박성훈
article thumbnail

https://www.acmicpc.net/problem/17615

 

17615번: 볼 모으기

첫 번째 줄에는 볼의 총 개수 N이 주어진다. (1 ≤ N ≤ 500,000) 다음 줄에는 볼의 색깔을 나타내는 문자 R(빨간색 볼) 또는 B(파란색 볼)가 공백 없이 주어진다. 문자열에는 R 또는 B 중 한 종류만 주

www.acmicpc.net

R이랑 B 두가지 색을 가진 공을 적절하게 이동시켜서 같은색끼리 모으는 문제이다.

 

처음 보고 들었던 생각은

R에 0

B에 1 이런느낌으로 숫자할당을 해서

swap 정렬횟수를 세는 inversion counting 유형인줄 알았다.

하지만 인접한 두 원소간의 교환이 아니라서 해당 가설(?) 은 부정됨.

 

두번째로 생각했던 것은

<그림 3>에서처럼

R이 뭉쳐져 있는 쪽으로 남은 R을 이동시키는게

이동 연산횟수에서 이득을 볼 것이라는 생각을 했었다.

 

그래서

왼쪽에서 시작하는 R의 갯수 => sR

왼쪽에서 시작하는 B의 갯수 => sB

오른쪽에서 '' => eR

오른쪽에서 '' => eB

 

이렇게 네 가지 경우에 대한 숫자를 세줬고,

 

어떤 특정한 끝 부분에 N개의 연속한 공이 모여있다면

전체 M개의 같은 색상 공들에 대해서

M-N번 이동 연산을 해줘야 한쪽으로 모을 수 있기 때문에,

각 경우에 대해서 M-N을 계산하고

그 최솟값을 출력해주면 된다.

 

#include <bits/stdc++.h>
using namespace std;

int main(){
	int N;
	string s;
	cin >> N;
	cin >> s;
	
	int sR = 0, sB = 0;
	int eR = 0, eB = 0;
	int cR = 0, cB = 0;
	
	for(int i=0; i<N; i++){
		if(s[i] == 'R') cR++;
		if(s[i] == 'B') cB++;
	}
	
	while(sR < N && s[sR] == 'R') sR++;
	while(sB < N && s[sB] == 'B') sB++;
	while(eR < N && s[N-1-eR] == 'R') eR++;
	while(eB < N && s[N-1-eB] == 'B') eB++;
	
	int ans = min({cR-sR, cB-sB, cR-eR, cB-eB});
	cout << ans;
	return 0;
}
반응형