AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC074-C Sugar Water
C#のソース
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("1 2 10 20 15 200");
//110 10
}
else if (InputPattern == "Input2") {
WillReturn.Add("1 2 1 2 100 1000");
//200 100
}
else if (InputPattern == "Input3") {
WillReturn.Add("17 19 22 26 55 2802");
//2634 934
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static long mA;
static long mB;
static long mC;
static long mD;
static long mE;
static long mF;
static void Main()
{
checked {
List<string> InputList = GetInputList();
long[] wkArr = InputList[0].Split(' ').Select(pX => long.Parse(pX)).ToArray();
mA = wkArr[0];
mB = wkArr[1];
mC = wkArr[2];
mD = wkArr[3];
mE = wkArr[4];
mF = wkArr[5];
long[] WaterSumArr = ExecDFS(mA * 100, mB * 100);
long[] SugarSumArr = ExecDFS(mC, mD);
decimal Answer = decimal.MinValue;
long AnswerWaterSum = 0;
long AnswerSugarSum = 0;
foreach (long EachWaterSum in WaterSumArr) {
if (EachWaterSum == 0) continue; // 水が無しは、除外
// 溶ける砂糖の上限
long SugarSumLimit = EachWaterSum / 100 * mE;
foreach (long EachSugarSum in SugarSumArr) {
// 質量は、F以下の必要あり
if (EachWaterSum + EachSugarSum > mF) break;
// 溶ける砂糖の上限と比較
if (EachSugarSum > SugarSumLimit) break;
decimal Bunsi = (decimal)(EachSugarSum * 100);
decimal Bunbo = (decimal)(EachWaterSum + EachSugarSum);
if (Bunbo > 0M) {
decimal AnswerKouho = Bunsi / Bunbo;
if (Answer < AnswerKouho) {
Answer = AnswerKouho;
AnswerWaterSum = EachWaterSum;
AnswerSugarSum = EachSugarSum;
}
}
}
}
Console.WriteLine("{0} {1}", AnswerWaterSum + AnswerSugarSum, AnswerSugarSum);
}
}
struct JyoutaiDef
{
internal long SumVal;
}
// DFSで、2つの数の和で作成可能な数の、配列を返す
static long[] ExecDFS(long pBase1, long pBase2)
{
var WillReturn = new HashSet<long>();
var Stk = new Stack<JyoutaiDef>();
JyoutaiDef WillPush;
WillPush.SumVal = 0;
Stk.Push(WillPush);
while (Stk.Count > 0) {
JyoutaiDef Popped = Stk.Pop();
// 再訪防止
if (WillReturn.Add(Popped.SumVal) == false)
continue;
WillPush.SumVal = Popped.SumVal + pBase1;
if (WillPush.SumVal <= mF) Stk.Push(WillPush);
WillPush.SumVal = Popped.SumVal + pBase2;
if (WillPush.SumVal <= mF) Stk.Push(WillPush);
}
return WillReturn.OrderBy(pX => pX).ToArray();
}
}
解説
深さ優先探索で、考えられる、水と砂糖の質量を列挙して、
全ての組合せを試してます。