Baekjun—回転キュー[java]


ソース:https://www.acmicpc.net/problem/1021

問題の説明


志敏にはN個の要素を含む双方向ループQがある.志敏はこのキューからいくつかの要素を抽出したいと思っています.
志敏はこのキューで次の3つの演算を実行できます.
最初の要素を抽出します.この操作を実行すると、元のキューの要素はa 1、...、akだったのはa 2だったのか...、akと同じです.
1グリッドを左に移動します.この操作を実行すると、a 1,...、akはa 2、...、ak,a 1になります.
1つ右に移動します.この操作を実行すると、a 1,...、akはak,a 1,...,ak-1になります.
キューに最初に含まれる数Nが与えられる.そしてジミンが抽出する要素の位置を与える(この場所は最初のキューの場所です.)このとき、所定の順序でその要素を抽出するために必要な2、3回の演算の最大値を出力するプログラムを作成してください.
問題の説明は以下の通りです.
簡単に言えば、

このような円形のキューがあり、index 0から1つの数字しか取り出せません.
入力した数字を左右に1つずつ探します.
その時になったら最小回転数を逆さにすればいいです.

問題を解く

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.StringTokenizer;

public class Main {
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine());
        int len = Integer.parseInt(st.nextToken());
        int total = Integer.parseInt(st.nextToken());
        LinkedList<Integer> ll = new LinkedList<>();
        LinkedList<Integer> ll2 = new LinkedList<>();
        st = new StringTokenizer(br.readLine());
        for (int i = 1; i <= len; i++) {
            ll.add(i);
            ll2.add(i);
        }
        int count = 0;
        while (total-- > 0) {
            int clockwiseCount = 0;
            int counterClockwiseCount = 0;
            int cur = Integer.parseInt(st.nextToken());
            while (true) {
                int first = ll.pollFirst();
                if (first != cur) {
                    clockwiseCount++;
                    ll.addLast(first);
                } else
                    break;
            }
            while (true) {
                int first = ll2.getFirst();
                if (first == cur) {
                    ll2.pollFirst();
                    break;
                }
                int last = ll2.pollLast();
                counterClockwiseCount++;
                ll2.addFirst(last);
            }
            count += Math.min(clockwiseCount, counterClockwiseCount);
        }
        System.out.println(count);
        br.close();
    }
}
前後ともにLinkedList資料構造を用いて数字を抽出する.
2つの時計回り、反時計回りに回転するLinkedListを作成しました.
各数字が見つかるたびに、時計回り、時計回りの回転数の少ない方がcountに加算されます.