AtCoderのABC
次のABCの問題へ
前のABCの問題へ
ABC279-F BOX
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("5 10");
WillReturn.Add("3 5");
WillReturn.Add("1 1 4");
WillReturn.Add("2 1");
WillReturn.Add("2 4");
WillReturn.Add("3 7");
WillReturn.Add("1 3 1");
WillReturn.Add("3 4");
WillReturn.Add("1 1 4");
WillReturn.Add("3 7");
WillReturn.Add("3 6");
//5
//4
//3
//1
//3
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
// 代表ボール[ボール]なDict;
static Dictionary<int, int> mDictA = new Dictionary<int, int>();
// 箱[ボール]なDict;
static Dictionary<int, int> mDictB = new Dictionary<int, int>();
// ボール[箱]なDict;
static Dictionary<int, int> mDictC = new Dictionary<int, int>();
static void Main()
{
List<string> InputList = GetInputList();
int[] wkArr = { };
Action<string> SplitAct = pStr =>
wkArr = pStr.Split(' ').Select(pX => int.Parse(pX)).ToArray();
SplitAct(InputList[0]);
int N = wkArr[0];
for (int I = 1; I <= N; I++) {
mDictA[I] = I;
mDictB[I] = I;
mDictC[I] = I;
}
var sb = new System.Text.StringBuilder();
int NextBall = N + 1;
foreach (string EachStr in InputList.Skip(1)) {
SplitAct(EachStr);
int Type = wkArr[0];
if (Type == 1) { // 箱にあるボールを移動
int ToBox = wkArr[1];
int FromBox = wkArr[2];
// 移動元の箱にボールがない場合
if (mDictC.ContainsKey(FromBox) == false) {
continue;
}
int MoveBall = mDictC[FromBox];
// 移動先の箱にボールがない場合
if (mDictC.ContainsKey(ToBox) == false) {
mDictB[MoveBall] = ToBox;
mDictC[ToBox] = MoveBall;
}
else {
int OyaBall = mDictC[ToBox];
mDictA[MoveBall] = OyaBall;
mDictB[MoveBall] = ToBox;
}
mDictC.Remove(FromBox);
}
if (Type == 2) { // 箱にボールを追加
int ToBox = wkArr[1];
if (mDictC.ContainsKey(ToBox)) {
int OyaBall = mDictC[ToBox];
mDictA[NextBall] = OyaBall;
mDictB[NextBall] = ToBox;
}
else {
mDictA[NextBall] = NextBall;
mDictB[NextBall] = ToBox;
mDictC[ToBox] = NextBall;
}
NextBall++;
}
if (Type == 3) { // ボールに入ってる箱の番号を答える
int Ball = wkArr[1];
var ChangeList = new List<int>(); // ポインタの付け替え用
while (Ball != mDictA[Ball]) {
ChangeList.Add(Ball);
Ball = mDictA[Ball];
}
ChangeList.ForEach(pX => mDictA[pX] = Ball);
int Box = mDictB[Ball];
sb.Append(Box);
sb.AppendLine();
}
}
Console.Write(sb.ToString());
}
}
解説
データベースのテーブル設計の要領で、
●DictA 代表ボール[ボール]
●DictB 箱[ボール]
●DictC 代表ボール[箱]
の3つのDictionaryを用意してます。
DictAには、UnionFindの経路圧縮を行ってます。