結果
問題 | No.367 ナイトの転身 |
ユーザー |
![]() |
提出日時 | 2024-10-13 07:54:18 |
言語 | C#(csc) (csc 3.9.0) |
結果 |
AC
|
実行時間 | 285 ms / 2,000 ms |
コード長 | 5,082 bytes |
コンパイル時間 | 998 ms |
コンパイル使用メモリ | 109,568 KB |
実行使用メモリ | 41,344 KB |
最終ジャッジ日時 | 2024-10-13 07:54:22 |
合計ジャッジ時間 | 3,568 ms |
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 27 |
コンパイルメッセージ
Microsoft (R) Visual C# Compiler version 3.9.0-6.21124.20 (db94f4cc) Copyright (C) Microsoft Corporation. All rights reserved.
ソースコード
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("4 4");WillReturn.Add("...G");WillReturn.Add(".RR.");WillReturn.Add(".RR.");WillReturn.Add("S...");//3//例えば(4, 1) -> (2, 2) -> (3, 3) -> (1, 4)//と移動すると最短手数でクリアできます。//このとき、駒は ナイト -> ミニビショップ -> ナイト と変化します。}else if (InputPattern == "Input2") {WillReturn.Add("3 4");WillReturn.Add("...G");WillReturn.Add("....");WillReturn.Add("S...");//3//この例ではチェス盤に赤いマスはありません。//例えば (3, 1) -> (1, 2) -> (3, 3) -> (1, 4)//と移動すると最短手数でクリアできます。}else if (InputPattern == "Input3") {WillReturn.Add("3 3");WillReturn.Add(".R.");WillReturn.Add("RGR");WillReturn.Add("SR.");//-1//この例では、駒はゴール地点に到達することができません。}else {string wkStr;while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);}return WillReturn;}static int UB_X;static int UB_Y;struct JyoutaiDef{internal int Level;internal int CurrX;internal int CurrY;internal bool IsKnight;}static void Main(){List<string> InputList = GetInputList();int[] wkArr = InputList[0].Split(' ').Select(X => int.Parse(X)).ToArray();int H = wkArr[0];int W = wkArr[1];char[,] BanArr = new char[W, H];UB_X = W - 1;UB_Y = H - 1;int StaX = -1, StaY = -1, GoalX = -1, GoalY = -1;for (int X = 0; X <= UB_X; X++) {for (int Y = 0; Y <= UB_Y; Y++) {BanArr[X, Y] = InputList[Y + 1][X];if (BanArr[X, Y] == 'S') {StaX = X; StaY = Y;}if (BanArr[X, Y] == 'G') {GoalX = X; GoalY = Y;}}}var Que = new Queue<JyoutaiDef>();JyoutaiDef WillEnqueue;WillEnqueue.Level = 0;WillEnqueue.CurrX = StaX;WillEnqueue.CurrY = StaY;WillEnqueue.IsKnight = true;Que.Enqueue(WillEnqueue);var VisitedSet = new HashSet<int>();VisitedSet.Add(GetHash(WillEnqueue));while (Que.Count > 0) {JyoutaiDef Dequeued = Que.Dequeue();//クリア判定if (Dequeued.CurrX == GoalX && Dequeued.CurrY == GoalY) {Console.WriteLine(Dequeued.Level);return;}Action<int, int> EnqueueSyori = (pNewX, pNewY) =>{if (pNewX < 0 || UB_X < pNewX) return;if (pNewY < 0 || UB_Y < pNewY) return;WillEnqueue.Level = Dequeued.Level + 1;WillEnqueue.CurrX = pNewX;WillEnqueue.CurrY = pNewY;WillEnqueue.IsKnight = Dequeued.IsKnight;if (BanArr[pNewX, pNewY] == 'R') {WillEnqueue.IsKnight = !WillEnqueue.IsKnight;}//再訪は不可if (VisitedSet.Add(GetHash(WillEnqueue)) == false)return;Que.Enqueue(WillEnqueue);};if (Dequeued.IsKnight) {EnqueueSyori(Dequeued.CurrX - 1, Dequeued.CurrY - 2);EnqueueSyori(Dequeued.CurrX + 1, Dequeued.CurrY - 2);EnqueueSyori(Dequeued.CurrX - 2, Dequeued.CurrY - 1);EnqueueSyori(Dequeued.CurrX + 2, Dequeued.CurrY - 1);EnqueueSyori(Dequeued.CurrX - 2, Dequeued.CurrY + 1);EnqueueSyori(Dequeued.CurrX + 2, Dequeued.CurrY + 1);EnqueueSyori(Dequeued.CurrX - 1, Dequeued.CurrY + 2);EnqueueSyori(Dequeued.CurrX + 1, Dequeued.CurrY + 2);}else {EnqueueSyori(Dequeued.CurrX - 1, Dequeued.CurrY - 1);EnqueueSyori(Dequeued.CurrX + 1, Dequeued.CurrY - 1);EnqueueSyori(Dequeued.CurrX - 1, Dequeued.CurrY + 1);EnqueueSyori(Dequeued.CurrX + 1, Dequeued.CurrY + 1);}}Console.WriteLine(-1);}//現在位置とIsKnightからハッシュ値を求めるstatic int GetHash(JyoutaiDef pJyoutai){int Hash = pJyoutai.CurrX * 10000;Hash += pJyoutai.CurrY * 10;Hash += (pJyoutai.IsKnight ? 1 : 0);return Hash;}}