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

ABC-123-B Five Dishes

■■■問題■■■

AtCoder料理店では、以下の5つの料理が提供されています。
ここで、「調理時間」は料理を注文してから客に届くまでの時間とします。

●ABC丼: 調理時間A分
●ARCカレー: 調理時間B分
●AGCパスタ: 調理時間C分
●APCラーメン: 調理時間D分
●ATCハンバーグ: 調理時間E分

また、この店には以下のような「注文のルール」があります。 

●注文は、10 の倍数の時刻 (時刻 0,10,20,30, ・・・ ) にしかできない。
●一回の注文につき一つの料理しか注文できない。
●ある料理を注文したら、それが届くまで別の注文ができない。
  ただし、料理が届いたちょうどの時刻には注文ができる。

E869120君は時刻0に料理店に着きました。
彼は5つの料理全てを注文します。最後の料理が届く最も早い時刻を求めてください。
ただし、料理を注文する順番は自由であり、時刻0に注文することも可能とします。

■■■入力■■■

A
B
C
D
E

●A,B,C,D,Eは1以上123以下の整数

■■■出力■■■

最後の料理が届く最も早い時刻を整数で出力せよ。 


C#のソース

using System;
using System.Collections.Generic;

class Program
{
    static string InputPattern = "InputX";

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

        if (InputPattern == "Input1") {
            WillReturn.Add("29");
            WillReturn.Add("20");
            WillReturn.Add("7");
            WillReturn.Add("35");
            WillReturn.Add("120");
            //215
            //ABC丼 → ARCカレー → AGCパスタ → ATCハンバーグ → APCラーメン の順に注文することにすると、
            //各料理の最も早い注文時刻・届く時刻は以下の通りになります。
            //●時刻  0にABC丼を注文する。時刻 29 に ABC丼が届く。
            //●時刻 30にARCカレーを注文する。時刻 50 に ARCカレーが届く。
            //●時刻 50にAGCパスタを注文する。時刻 57 に AGCパスタが届く。
            //●時刻 60にATCハンバーグを注文する。時刻 180 に ATCハンバーグが届く。
            //●時刻180にAPCラーメンを注文する。時刻 215 に APCラーメンが届く。
            //これより早く最後の料理が届くような方法は存在しません。
        }
        else if (InputPattern == "Input2") {
            WillReturn.Add("101");
            WillReturn.Add("86");
            WillReturn.Add("119");
            WillReturn.Add("108");
            WillReturn.Add("57");
            //481
            //AGC パスタ→ARC カレー→ATC ハンバーグ→APC ラーメン→ABC 丼の順に注文することにすると、
            //各料理の最も早い注文時刻・届く時刻は以下の通りになります。
            //●時刻  0にAGCパスタを注文する。時刻 119に AGCパスタが届く。
            //●時刻120にARCカレーを注文する。時刻 206に ARCカレーが届く。
            //●時刻210にATCハンバーグを注文する。時刻 267に ATCハンバーグが届く。
            //●時刻270にAPCラーメンを注文する。時刻 378に APCラーメンが届く。
            //●時刻380にABC丼を注文する。時刻 481 に ABC丼が届く。
            //これより早く最後の料理が届くような方法は存在しません。
        }
        else if (InputPattern == "Input3") {
            WillReturn.Add("123");
            WillReturn.Add("123");
            WillReturn.Add("123");
            WillReturn.Add("123");
            WillReturn.Add("123");
            //643
            //これが入力される最大のケースです。
        }
        else {
            string wkStr;
            while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
        }
        return WillReturn;
    }

    static void Main()
    {
        List<string> InputList = GetInputList();

        var ValList = new List<int>();
        for (int I = 0; I <= InputList.Count - 1; I++) {
            ValList.Add(int.Parse(InputList[I]));
        }

        int AnswerSum = int.MaxValue;
        foreach (int[] EachIntArr in RubyPatternCnt.Permutation(ValList.ToArray(), ValList.Count)) {
            int CurrSum = 0;
            foreach (int EachInt in EachIntArr) {
                if (CurrSum % 10 == 1) CurrSum += 9;
                if (CurrSum % 10 == 2) CurrSum += 8;
                if (CurrSum % 10 == 3) CurrSum += 7;
                if (CurrSum % 10 == 4) CurrSum += 6;
                if (CurrSum % 10 == 5) CurrSum += 5;
                if (CurrSum % 10 == 6) CurrSum += 4;
                if (CurrSum % 10 == 7) CurrSum += 3;
                if (CurrSum % 10 == 8) CurrSum += 2;
                if (CurrSum % 10 == 9) CurrSum += 1;

                CurrSum += EachInt;
            }
            AnswerSum = Math.Min(AnswerSum, CurrSum);
        }
        Console.WriteLine(AnswerSum);
    }

    //Rubyの場合の数
    internal static class RubyPatternCnt
    {
        //順列を返す
        private struct JyoutaiDef_Permutation
        {
            internal List<int> SelectedIndList;
        }
        internal static IEnumerable<int[]> Permutation(int[] pArr, int pR)
        {
            if (pR == 0) yield break;
            if (pArr.Length < pR) yield break;

            var stk = new Stack<JyoutaiDef_Permutation>();
            JyoutaiDef_Permutation WillPush;
            for (int I = pArr.GetUpperBound(0); 0 <= I; I--) {
                WillPush.SelectedIndList = new List<int>() { I };
                stk.Push(WillPush);
            }

            while (stk.Count > 0) {
                JyoutaiDef_Permutation Popped = stk.Pop();

                //クリア判定
                if (Popped.SelectedIndList.Count == pR) {
                    var WillReturn = new List<int>();
                    Popped.SelectedIndList.ForEach(X => WillReturn.Add(pArr[X]));
                    yield return WillReturn.ToArray();
                    continue;
                }

                for (int I = pArr.GetUpperBound(0); 0 <= I; I--) {
                    if (Popped.SelectedIndList.Contains(I)) continue;
                    WillPush.SelectedIndList = new List<int>(Popped.SelectedIndList) { I };
                    stk.Push(WillPush);
                }
            }
        }
    }
}


解説

順列を返すライブラリを使用して、5!で120通りしかないので全探索してます。