トップページに戻る
次の競技プログラミングの問題へ
前の競技プログラミングの問題へ
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通りしかないので全探索してます。