トップページに戻る    次の競技プログラミングの問題へ    前の競技プログラミングの問題へ

ABC-035-B ドローン

■■■問題■■■

無限に広い二次元グリッドの原点(0,0)に高橋君と1台のドローンがいます。
このドローンは文字列が与えられた時、
文字列の先頭から末尾までのそれぞれの文字を1つの命令と解釈して順に実行します。
命令は以下の4種類です。

●'L' 現在のドローンの位置を(x,y)として(x-1,y)に移動する
●'R' 現在のドローンの位置を(x,y)として(x+1,y)に移動する
●'U' 現在のドローンの位置を(x,y)として(x,y+1)に移動する
●'D' 現在のドローンの位置を(x,y)として(x,y-1)に移動する

今、ドローンに何らかの命令が与えられ、どこかへと移動しました。
高橋君はドローンに送られた命令を表す文字列であるSを手に入れたものの、
いくつかの箇所は破損し'?'になり分からなくなってしまいました。
ただし、'?'が元々は'L'、'R'、'U'、'D'のいずれかの文字だったことが分かっています。

ドローンと高橋君の距離はドローンの位置を(x,y)として
マンハッタン距離 |x|+|y| で表されます。

求める値の種類を表す整数Tが与えられるので、
移動を終えたあとのドローンと高橋君の距離としてありうる値のうち、
T=1ならば最大値を、T=2ならば最小値を求めてください。

■■■入力■■■

S
T

●1行目にドローンに与えられた命令を表す文字列 S(1 <= |S| <= 10万) が与えられる。
  ここで、 |S| は文字列 S の長さを表す。
●Sは'L'、'R'、'U'、'D'、'?'の5種類の文字のみからなる。
●2行目に求める値の種類を表す整数 T(1 <= T <= 2) が与えられる。

■■■出力■■■

●T=1ならば移動を終えたあとのドローンと高橋君の距離としてありうる値のうち、最大値を1行に出力せよ。
●T=2ならば移動を終えたあとのドローンと高橋君の距離としてありうる値のうち、最小値を1行に出力せよ。


C#のソース

using System;
using System.Collections.Generic;

class Program
{
    static string InputPattern = "Input1";

    static List<string> GetInputList()
    {
        var WillReturn = new List<string>();

        if (InputPattern == "Input1") {
            WillReturn.Add("UL?");
            WillReturn.Add("1");
            //3
            //ドローンが最終的にいる可能性がある位置は
            //(-2,1),(-1,0),(-1,2),(0,1)の4つです。
            //ドローンと高橋君の距離 |x|+|y| のうち最大値は3となります。
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("UD?");
            WillReturn.Add("1");
            //1
            //ドローンが最終的にいる可能性がある位置は
            //(1,0),(-1,0),(0,1),(0,-1) の 4 つです。
            //ドローンと高橋君の距離 |x|+|y| のうち最大値は1となります。
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("UUUU?DDR?LLLL");
            WillReturn.Add("1");
            //7
        }
        else if (InputPattern == "Input4") {
            WillReturn.Add("UULL?");
            WillReturn.Add("2");
            //3
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    static void Main()
    {
        List<string> InputList = GetInputList();
        string S = InputList[0];
        int T = int.Parse(InputList[1]);

        int CurrX = 0;
        int CurrY = 0;
        int HatenaCnt = 0;
        foreach (char EachChar in S) {
            if (EachChar == 'L') CurrX--;
            if (EachChar == 'R') CurrX++;
            if (EachChar == 'U') CurrY++;
            if (EachChar == 'D') CurrY--;
            if (EachChar == '?') HatenaCnt++;
        }

        for (int I = 1; I <= HatenaCnt; I++) {
            if (T == 1) { //原点からの距離を最大
                if (CurrX >= 0) CurrX++;
                else if (CurrX < 0) CurrX--;
            }
            if (T == 2) { //原点からの距離を最小
                if (CurrX > 0) CurrX--;
                else if (CurrX < 0) CurrX++;
                else if (CurrY > 0) CurrY--;
                else if (CurrY < 0) CurrY++;
                else CurrX++;
            }
        }
        Console.WriteLine(Math.Abs(CurrX) + Math.Abs(CurrY));
    }
}


解説

?の数をカウントして、原点からの距離が最小または最大となるように移動してます。

ベクトルの加算は交換法則が成立するので、?は後回しでも問題ありません。