結果
問題 | No.5006 Hidden Maze |
ユーザー |
![]() |
提出日時 | 2022-06-12 17:42:56 |
言語 | C# (.NET 8.0.404) |
結果 |
AC
|
実行時間 | 599 ms / 2,000 ms |
コード長 | 8,591 bytes |
コンパイル時間 | 7,105 ms |
実行使用メモリ | 69,700 KB |
スコア | 56,402 |
平均クエリ数 | 436.98 |
最終ジャッジ日時 | 2022-06-12 17:43:41 |
合計ジャッジ時間 | 42,151 ms |
ジャッジサーバーID (参考情報) |
judge13 / judge12 |
純コード判定しない問題か言語 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 100 |
コンパイルメッセージ
Determining projects to restore... Restored /home/judge/data/code/main.csproj (in 102 ms). .NET 向け Microsoft (R) Build Engine バージョン 17.0.0-preview-21470-01+cb055d28f Copyright (C) Microsoft Corporation.All rights reserved. プレビュー版の .NET を使用しています。https://aka.ms/dotnet-core-preview をご覧ください main -> /home/judge/data/code/bin/Release/net6.0/main.dll main -> /home/judge/data/code/bin/Release/net6.0/publish/
ソースコード
using System;using System.Collections.Generic;using System.Diagnostics;using System.Linq;using System.Text;using static Constants;public static class Constants{public static readonly int N = 20;public static readonly Point[] Dirs ={new Point(-1, 0), // 左new Point(0, -1), // 上new Point(1, 0), // 右new Point(0, 1), // 下};}public class PriorityQueue<TKey, TValue>{SortedDictionary<TKey, Stack<TValue>> dict = new SortedDictionary<TKey, Stack<TValue>>();int count;public int Count{get{return count;}}public void Enqueue(TKey key, TValue value){Stack<TValue> set;if (!dict.TryGetValue(key, out set)){set = new Stack<TValue>();dict[key] = set;}set.Push(value);count++;}public KeyValuePair<TKey, TValue> Dequeue(){var queue = dict.First();if (queue.Value.Count <= 1){dict.Remove(queue.Key);}var val = queue.Value.Pop();count--;return new KeyValuePair<TKey, TValue>(queue.Key, val);}public KeyValuePair<TKey, TValue> Peek(){var queue = dict.First();var val = queue.Value.Peek();return new KeyValuePair<TKey, TValue>(queue.Key, val);}}public struct Point{public int X;public int Y;public static readonly Point Invalid = new Point(-1, -1);public static readonly Point Left = new Point(-1, 0);public static readonly Point Up = new Point(0, -1);public static readonly Point Right = new Point(1, 0);public static readonly Point Down = new Point(0, 1);public Point(Point p){X = p.X;Y = p.Y;}public Point(int x, int y){X = x;Y = y;}public static bool operator ==(Point a, Point b){return (a.X == b.X && a.Y == b.Y);}public static bool operator !=(Point a, Point b){return !(a == b);}//objと自分自身が等価のときはtrueを返すpublic override bool Equals(object obj){if (!(obj is Point)){return false;}Point p = (Point)obj;return (X == p.X && Y == p.Y);}//Equalsがtrueを返すときに同じ値を返すpublic override int GetHashCode(){return (X << 16) ^ Y;}public Point Clone(){return new Point(X, Y);}public void Reverse(){X = -X;Y = -Y;}public static Point operator +(Point a, Point b){return new Point(a.X + b.X, a.Y + b.Y);}public static Point operator -(Point a, Point b){return new Point(a.X - b.X, a.Y - b.Y);}public static Point operator *(Point a, int i){return new Point(a.X * i, a.Y * i);}public static Point operator /(Point a, int i){return new Point(a.X / i, a.Y / i);}public static Point operator +(Point a){return new Point(+a.X, +a.Y);}public static Point operator -(Point a){return new Point(-a.X, -a.Y);}public override string ToString(){return string.Format("({0},{1})", Y, X);}public Point Sign(){return new Point(Math.Sign(X), Math.Sign(Y));}public int Distance(Point p){return Math.Abs(this.X - p.X) + Math.Abs(this.Y - p.Y);}public char ToDirStr(){if (X < 0){return 'L';}if (X > 0){return 'R';}if (Y < 0){return 'U';}return 'D';}public bool InRange(){return 0 <= X && X < N && 0 <= Y && Y < N;}}public class Solver{readonly double P;int[,] RWall; // -1:壁はない 0以上:移動失敗回数int[,] DWall;List<Point>[,] Neighbors;public Solver(double p){P = p;RWall = new int[N, N];DWall = new int[N, N];InitNeighbors();}void InitNeighbors(){Neighbors = new List<Point>[N, N];for (int y = 0; y < N; y++){for (int x = 0; x < N; x++){Neighbors[y, x] = new List<Point>();var p = new Point(x, y);foreach (var dir in Dirs){var nei = p + dir;if (nei.InRange()){Neighbors[y, x].Add(nei);}}}}}int GetWallValue(Point cur, Point next){var dir = next - cur;if (dir.Y == 0){return RWall[cur.Y, Math.Min(cur.X, next.X)];}return DWall[Math.Min(cur.Y, next.Y), cur.X];}double GetProb(Point cur, Point next){var dir = next - cur;var wall = GetWallValue(cur, next);if (wall == 0){return 1.01;}if (wall == -1){return 1;}return Math.Pow(P, wall);}public (string, List<Point>) GetAction(){var start = new Point(0, 0);var goal = new Point(N - 1, N - 1);var prev = new Dictionary<Point, Point>();var queue = new PriorityQueue<double, Point>(); // 確率の降順queue.Enqueue(-1, start);prev[start] = start;while (queue.Count > 0){var kv = queue.Dequeue();var cur = kv.Value;var prob = -kv.Key;foreach (var next in Neighbors[cur.Y, cur.X]){if (prev.ContainsKey(next)){continue;}var nextProb = prob * GetProb(cur, next) * (1 - P) / next.Distance(goal);queue.Enqueue(-nextProb, next);prev[next] = cur;if (next == goal){break;}}}var way = new List<Point>();for (var p = goal; p != start; p = prev[p]){way.Add(p);}way.Add(start);way.Reverse();var acts = new StringBuilder();var pr = start;foreach (var p in way.Skip(1)){var dir = p - pr;acts.Append(dir.ToDirStr());pr = p;}return (acts.ToString(), way);}public void SetResult(List<Point> way, int step){for (int i = 0; i < step; i++){var cur = way[i];var next = way[i + 1];var dir = next - cur;if (dir.Y == 0){var y = cur.Y;var x = Math.Min(cur.X, next.X);RWall[y, x] = -1;}else{var y = Math.Min(cur.Y, next.Y);var x = cur.X;DWall[y, x] = -1;}}{var cur = way[step];var next = way[step + 1];var dir = next - cur;if (dir.Y == 0){var y = cur.Y;var x = Math.Min(cur.X, next.X);if (RWall[y, x] >= 0){RWall[y, x]++;}}else{var y = Math.Min(cur.Y, next.Y);var x = cur.X;if (DWall[y, x] >= 0){DWall[y, x]++;}}}}}public static class Solution{public static void Main(){var vals = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();var h = vals[0];var w = vals[1];var p = vals[2] * 0.01;var solver = new Solver(p);try{while (true){(var acts, var way) = solver.GetAction();Console.WriteLine(acts);var step = int.Parse(Console.ReadLine());if (step < 0){break;}solver.SetResult(way, step);}}catch (Exception e){Console.Error.WriteLine(e);}}}