본문 바로가기

알고리즘(백준 등) 공부

SWEA 10761. 신뢰

오렌지, 블루 두 로봇이 다른 복도에서 1번 위치부터 시작해서 정해진 순서대로 버튼을 누르기 위해 이동, 버튼 누르기, 가만히 있기를 수행할 때 소요되는 최소 시간을 구하는 문제이다. 버튼은 O x, B x와 같은 형태로 주어지는데, O x는 오렌지가 해당 버튼을 눌러야 함을 뜻하고, B x는 블루가 해당 버튼을 눌러야 함을 뜻한다.

 

서로 다른 복도에서 오렌지 혹은 블루가 버튼을 누르는 동안에도 이동할 수 있으므로 각각의 로봇에 명령을 저장하고 명령의 순서대로 이동하면서 다른 로봇도 최대한 이동시킨다. 이를 위해 로봇별로 List로 명령의 순서와 위치를 저장하여 더 빠른 명령을 수행하게 한다. 오렌지 혹은 블루의 남은 명령이 없다면 남은 명령을 가진 로봇만 수행하면 된다. 둘 다 있다면 둘 중 명령 번호가 작은 순서로 이동 및 버튼을 누르기 작업을 한 후, 해당 시간만큼 다른 로봇이 이동하게 한다.

static class Order {
    int position, time;
        
    public Order(int position, int time) {
        this.position = position;
        this.time = time;
    }
        
    @Override
    public String toString() {
        return position + " " + time;
    }
}
int time = 0;
int orange = 1, blue = 1;
while(!oranges.isEmpty() || !blues.isEmpty()) {
    Order nextOrange = null, nextBlue = null;
    if(!oranges.isEmpty()) nextOrange = oranges.get(0);
    if(!blues.isEmpty()) nextBlue = blues.get(0);
    if(nextOrange == null) {
        time += Math.abs(nextBlue.position - blue);
        time++;
        blue = nextBlue.position;
        blues.remove(0);
        continue;
    }
    if(nextBlue == null) {
        time += Math.abs(nextOrange.position - orange);
        time++;
        orange = nextOrange.position;
        oranges.remove(0);
        continue;
    }
    if(nextOrange.time > nextBlue.time) {
        int diff = Math.abs(nextBlue.position - blue) + 1;
        time += diff;
        blue = nextBlue.position;
        blues.remove(0);
        if(Math.abs(nextOrange.position - orange) > diff) {
            if(orange > nextOrange.position) orange -= diff;
            else orange += diff;
        } else {
            orange = nextOrange.position;
        }
    } else {
        int diff = Math.abs(nextOrange.position - orange) + 1;
        time += diff;
        orange = nextOrange.position;
        oranges.remove(0);
        if(Math.abs(nextBlue.position - blue) > diff) {
            if(blue > nextBlue.position) blue -= diff;
                else blue += diff;
        } else {
            blue = nextBlue.position;
        }
    }
}
sb.append(time).append('\n');

 

 

결과 코드는 다음과 같다.

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

public class Solution {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine());
        
        StringBuilder sb = new StringBuilder();
        for (int tc = 1; tc <= T; tc++) {
            sb.append('#').append(tc).append(' ');
            StringTokenizer st = new StringTokenizer(br.readLine());
            int n = Integer.parseInt(st.nextToken());
            List<Order> oranges = new ArrayList<>(), blues = new ArrayList<>();
            for(int i=0; i<n; i++) {
                char robot = st.nextToken().charAt(0);
                int button = Integer.parseInt(st.nextToken());
                if(robot == 'O') oranges.add(new Order(button, i));
                else blues.add(new Order(button, i));
            }
            
            int time = 0;
            int orange = 1, blue = 1;
            while(!oranges.isEmpty() || !blues.isEmpty()) {
                Order nextOrange = null, nextBlue = null;
                if(!oranges.isEmpty()) nextOrange = oranges.get(0);
                if(!blues.isEmpty()) nextBlue = blues.get(0);
                if(nextOrange == null) {
                    time += Math.abs(nextBlue.position - blue);
                    time++;
                    blue = nextBlue.position;
                    blues.remove(0);
                    continue;
                }
                if(nextBlue == null) {
                    time += Math.abs(nextOrange.position - orange);
                    time++;
                    orange = nextOrange.position;
                    oranges.remove(0);
                    continue;
                }
                if(nextOrange.time > nextBlue.time) {
                    int diff = Math.abs(nextBlue.position - blue) + 1;
                    time += diff;
                    blue = nextBlue.position;
                    blues.remove(0);
                    if(Math.abs(nextOrange.position - orange) > diff) {
                        if(orange > nextOrange.position) orange -= diff;
                        else orange += diff;
                    } else {
                        orange = nextOrange.position;
                    }
                } else {
                    int diff = Math.abs(nextOrange.position - orange) + 1;
                    time += diff;
                    orange = nextOrange.position;
                    oranges.remove(0);
                    if(Math.abs(nextBlue.position - blue) > diff) {
                        if(blue > nextBlue.position) blue -= diff;
                        else blue += diff;
                    } else {
                        blue = nextBlue.position;
                    }
                }
            }
            sb.append(time).append('\n');
        }
        
        br.close();
        System.out.print(sb);
    }
    
    static class Order {
        int position, time;
        
        public Order(int position, int time) {
            this.position = position;
            this.time = time;
        }
        
        @Override
        public String toString() {
            return position + " " + time;
        }
    }
}

'알고리즘(백준 등) 공부' 카테고리의 다른 글

SWEA 10726. 이진수 표현  (0) 2026.06.22
SWEA 10762. 사탕 나누기  (0) 2026.06.09
SWEA 10804. 문자열의 거울상  (0) 2026.06.09
SWEA 10912. 외로운 문자  (0) 2026.06.08
SWEA 10908. 짝수인 이항 계수  (0) 2026.06.07