AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC333-E Takahashi Quest
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("13");
WillReturn.Add("1 2");
WillReturn.Add("1 3");
WillReturn.Add("1 1");
WillReturn.Add("1 3");
WillReturn.Add("1 2");
WillReturn.Add("2 3");
WillReturn.Add("1 3");
WillReturn.Add("1 3");
WillReturn.Add("2 3");
WillReturn.Add("1 3");
WillReturn.Add("2 2");
WillReturn.Add("2 3");
WillReturn.Add("2 1");
//3
//1 1 1 0 0 1 0 1
}
else if (InputPattern == "Input2") {
WillReturn.Add("4");
WillReturn.Add("2 3");
WillReturn.Add("1 4");
WillReturn.Add("2 1");
WillReturn.Add("1 2");
//-1
}
else if (InputPattern == "Input3") {
WillReturn.Add("30");
WillReturn.Add("1 25");
WillReturn.Add("1 2");
WillReturn.Add("1 10");
WillReturn.Add("1 18");
WillReturn.Add("2 18");
WillReturn.Add("1 11");
WillReturn.Add("2 11");
WillReturn.Add("1 21");
WillReturn.Add("1 6");
WillReturn.Add("2 2");
WillReturn.Add("2 10");
WillReturn.Add("1 11");
WillReturn.Add("1 24");
WillReturn.Add("1 11");
WillReturn.Add("1 3");
WillReturn.Add("1 2");
WillReturn.Add("1 18");
WillReturn.Add("2 25");
WillReturn.Add("1 8");
WillReturn.Add("1 10");
WillReturn.Add("1 11");
WillReturn.Add("2 18");
WillReturn.Add("2 10");
WillReturn.Add("1 10");
WillReturn.Add("2 2");
WillReturn.Add("1 24");
WillReturn.Add("1 10");
WillReturn.Add("2 10");
WillReturn.Add("1 25");
WillReturn.Add("2 6");
//4
//1 1 1 1 1 0 1 0 0 0 0 1 1 0 1 0 1 0 0 0
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
struct EventDef
{
internal int Type;
internal int X;
}
static List<EventDef> mEventList = new List<EventDef>();
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => int.Parse(pX)).ToArray();
foreach (string EachStr in InputList.Skip(1)) {
SplitAct(EachStr);
EventDef WillAdd;
WillAdd.Type = wkArr[0];
WillAdd.X = wkArr[1];
mEventList.Add(WillAdd);
}
int UB = mEventList.Count - 1;
// モンスターの種類のSet
var MonsterSet = new HashSet<int>();
foreach (EventDef EachEvent in mEventList) {
MonsterSet.Add(EachEvent.X);
}
// ポーションを拾うIndのSet
var GetPortionIndSet = new HashSet<int>();
// 拾っていい数[ポーション]なDict
var CanGetPortionDict = new Dictionary<int, int>();
foreach (int EachMonster in MonsterSet) CanGetPortionDict[EachMonster] = 0;
for (int I = UB; 0 <= I; I--) {
int Type = mEventList[I].Type;
int X = mEventList[I].X;
if (Type == 1) {
if (CanGetPortionDict[X] > 0) {
CanGetPortionDict[X]--;
GetPortionIndSet.Add(I);
}
}
if (Type == 2) {
CanGetPortionDict[X]++;
}
}
// 持ってる数[ポーション]なDict
var PortionCntDict = new Dictionary<int, int>();
foreach (int EachMonster in MonsterSet) PortionCntDict[EachMonster] = 0;
int TotalPortionCnt = 0;
var TotalPortionCntList = new List<int>();
for (int I = 0; I <= UB; I++) {
int Type = mEventList[I].Type;
int X = mEventList[I].X;
if (Type == 1) {
if (GetPortionIndSet.Contains(I)) {
PortionCntDict[X]++;
TotalPortionCnt++;
}
}
if (Type == 2) {
if (PortionCntDict[X] == 0) {
Console.WriteLine(-1);
return;
}
PortionCntDict[X]--;
TotalPortionCnt--;
}
TotalPortionCntList.Add(TotalPortionCnt);
}
Console.WriteLine(TotalPortionCntList.Max());
var AnswerList = new List<int>();
for (int I = 0; I <= UB; I++) {
int Type = mEventList[I].Type;
int X = mEventList[I].X;
if (Type == 1) {
if (GetPortionIndSet.Contains(I)) {
AnswerList.Add(1);
}
else {
AnswerList.Add(0);
}
}
}
Console.WriteLine(IntEnumJoin(" ", AnswerList));
}
// セパレータとInt型の列挙を引数として、結合したstringを返す
static string IntEnumJoin(string pSeparater, IEnumerable<int> pEnum)
{
string[] StrArr = Array.ConvertAll(pEnum.ToArray(), pX => pX.ToString());
return string.Join(pSeparater, StrArr);
}
}
解説
モンスターの種類が1種類のみで考察すると、
逆から貪欲で、良いと分かります。