AOJ本の読書メモ
AOJ
次のAOJの問題へ
前のAOJの問題へ
AOJ 0675 テンキー
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("100000 13");
//5
}
else if (InputPattern == "Input2") {
WillReturn.Add("4 3");
//3
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static long[] GetSplitArr(string pStr)
{
return (pStr == "" ? new string[0] : pStr.Split(' ')).Select(pX => long.Parse(pX)).ToArray();
}
static void Main()
{
List<string> InputList = GetInputList();
long[] wkArr = GetSplitArr(InputList[0]);
long Hou = wkArr[0];
long GoalVal = wkArr[1];
var Que = new Queue<JyoutaiDef>();
JyoutaiDef WillEnqueue;
WillEnqueue.CurrX = 0;
WillEnqueue.CurrY = 3;
WillEnqueue.Level = 0;
WillEnqueue.Val = 0;
Que.Enqueue(WillEnqueue);
var VisitedSet = new HashSet<long>();
while (Que.Count > 0) {
JyoutaiDef Dequeued = Que.Dequeue();
long Hash = GetHash(Dequeued);
if (VisitedSet.Add(Hash) == false) {
continue;
}
// クリア判定
if (Dequeued.Val == GoalVal) {
Console.WriteLine(Dequeued.Level);
return;
}
// 移動する遷移
Action<long, long> EnqueueAct = (long pNewX, long pNewY) =>
{
// 範囲外はNG
if (GetNum(pNewX, pNewY) == null) {
return;
}
WillEnqueue.CurrX = pNewX;
WillEnqueue.CurrY = pNewY;
WillEnqueue.Level = Dequeued.Level + 1;
WillEnqueue.Val = Dequeued.Val;
Que.Enqueue(WillEnqueue);
};
EnqueueAct(Dequeued.CurrX, Dequeued.CurrY - 1);
EnqueueAct(Dequeued.CurrX, Dequeued.CurrY + 1);
EnqueueAct(Dequeued.CurrX - 1, Dequeued.CurrY);
EnqueueAct(Dequeued.CurrX + 1, Dequeued.CurrY);
// 数値を設定する遷移
long? CurrNum = GetNum(Dequeued.CurrX, Dequeued.CurrY);
WillEnqueue.CurrX = Dequeued.CurrX;
WillEnqueue.CurrY = Dequeued.CurrY;
WillEnqueue.Level = Dequeued.Level + 1;
WillEnqueue.Val = Dequeued.Val * 10 + CurrNum.Value;
WillEnqueue.Val %= Hou;
Que.Enqueue(WillEnqueue);
}
}
static long GetHash(JyoutaiDef pJyoutai)
{
long Hash = 0;
Hash += pJyoutai.CurrX;
Hash *= 10;
Hash += pJyoutai.CurrY;
Hash *= 1000000;
Hash += pJyoutai.Val;
return Hash;
}
struct JyoutaiDef
{
internal long CurrX;
internal long CurrY;
internal long Level;
internal long Val;
}
// 現在座標を引数として、テンキーの値を返す
// 範囲外ならnullを返す
static long? GetNum(long pX, long pY)
{
if (pY == 0 && pX == 0) return 7;
if (pY == 0 && pX == 1) return 8;
if (pY == 0 && pX == 2) return 9;
if (pY == 1 && pX == 0) return 4;
if (pY == 1 && pX == 1) return 5;
if (pY == 1 && pX == 2) return 6;
if (pY == 2 && pX == 0) return 1;
if (pY == 2 && pX == 1) return 2;
if (pY == 2 && pX == 2) return 3;
if (pY == 3 && pX == 0) return 0;
return null;
}
}
解説
BFSしてます。
0から9と
modの値が0から100000 なので、
状態数は
10*100000 = 1000000
なため、{ノード , 余りの値 } で再訪防止でBFSしてます。