1. 문제

17615번: 볼 모으기



2. 개요

파란 볼과 빨간 볼이 일렬로 늘어서 있고 볼들을 이동시켜 같은 볼끼리 인접하게 하려 한다.

볼을 이동시킬 때, 옆에 다른 색의 볼이 있다면 한 번에 다 뛰어넘을 수 있다.

또한 어떤 색의 볼을 이동시켰다면 그 색의 볼만 이동시킬 수 있다.

이 때 같은 색의 볼들끼리 인접시키는 최소한의 이동 횟수를 구하는 문제.



3. 풀이 및 코드

3-1. 풀이

같은 볼들끼리 인접시키게 되면 결국 한쪽은 파란색 한쪽은 빨간색이 된다.

이동 방향이 정해지면 이미 그쪽에 모여있는 색의 공들은 신경 쓸 필요가 없어진다.

그 모여있는 공들을 제외한 상황에서 한 색상을 정해 이동 횟수를 세면 된다.

처음에는 문제 그림만 보고 오른쪽으로만 이동한다고 생각했었는데 왼쪽으로도 이동이 가능하다.

이는 문자열을 뒤집어서 같은 방식으로 해결 가능하다.

3-2. Python

import sys

N = int(sys.stdin.readline())

s = sys.stdin.readline().rstrip()
slen = len(s)

def find(ss, color):
    count = 0
    for i in range(slen - 1, -1, -1):
        if ss[i] != color:
            break

        count += 1

    return ss.count(color) - count

answer = min(find(s, 'R'), find(s, 'B'), find(s[::-1], 'R'), find(s[::-1], 'B'))
print(answer)

3-3. C#

using System.Linq;

namespace boj_17615
{
    internal class Program
    {
        static int answer;

        static void Main(string[] args)
        {
            int N = int.Parse(Console.ReadLine());

            string s = Console.ReadLine();

            answer = s.Length;

            Find(s, 'R');
            Find(s, 'B');
            string ss = new string(s.Reverse().ToArray());
            Find(ss, 'R');
            ss = new string(s.Reverse().ToArray());
            Find(ss, 'B');

            Console.WriteLine(answer);
        }

        static void Find(string balls, char color)
        {
            int count = 0;

            for (int i = 0; i < balls.Length; i++)
            {
                if (balls[i] != color)
                    break;
                    
                count++;
            }

            answer = (int)MathF.Min(answer, balls.Count(x => x == color) - count);
        }
    }
}

Comments