AOJ 1336: 最後に出てくるアリをシミュレーションする

問題

The Last Ant | Aizu Online Judge

N引きのアリが直線の巣穴の中を動いている。それぞれの位置と向きが与えられ、一定の速さでその方向に動く。2引きのアリが出会う時、巣穴の広いところで出会えればすれ違うだけだが、狭いところで出会うとぶつかって向きを変えてしまう。最後のアリが出てくるまでの時間と、最後のアリが誰かを求めよ。

f:id:kenkoooo:20150202020621p:plain

解法

ルール通りにシミュレーションすれば良い。

コード

import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;

public class Main {

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        while (true) {
            int n = sc.nextInt();
            if (n == 0) {
                sc.close();
                break;
            }
            int l = sc.nextInt();

            char[] dir = new char[n];
            int[] place = new int[n];
            for (int i = 0; i < n; i++) {
                dir[i] = sc.next().charAt(0);
                place[i] = sc.nextInt();
            }

            int time = 0;
            while (true) {
                time++;
                for (int i = 0; i < n; i++) {
                    if (place[i] < 1 && place[i] >= l) {
                        continue;
                    }
                    if (dir[i] == 'R') {
                        place[i]++;
                    } else {
                        place[i]--;
                    }
                }

                ArrayList<Integer> inside = new ArrayList<Integer>();
                for (int p = 1; p < l; p++) {
                    ArrayList<Integer> list = new ArrayList<Integer>();
                    for (int ant = 0; ant < n; ant++) {
                        if (place[ant] == p) {
                            list.add(ant);
                            inside.add(ant);
                        }
                    }

                    // ぶつかった奴は向きを変える
                    if (list.size() >= 2) {
                        for (Integer ant : list) {
                            if (dir[ant] == 'R') {
                                dir[ant] = 'L';
                            } else {
                                dir[ant] = 'R';
                            }
                        }
                    }
                }

                if (inside.size() == 1) {
                    // 最後に残っているアリが1匹いた場合
                    int ant = inside.get(0);
                    if (dir[ant] == 'R') {
                        // 右向きならtimeにplace[ant]がlになるまでの時間を足す
                        int rest = l - place[ant];
                        System.out.println((time + rest) + " " + (ant + 1));
                    } else {
                        // 左向きならtimeにplace[ant]が0になるまでの時間を足す
                        System.out.println((time + place[ant]) + " "
                                + (ant + 1));
                    }
                    break;
                } else if (inside.size() == 2) {
                    int antL = inside.get(0);
                    int antR = inside.get(1);

                    if (dir[antL] == 'L' && place[antL] == 1
                            && dir[antR] == 'R' && place[antR] == l - 1) {
                        // 2匹同時退出の場合、左側のアリを出力
                        System.out.println((time + 1) + " " + (antL + 1));
                        break;
                    }
                }

            }

        }

    }
}