結果

問題 No.1323 うしらずSwap
ユーザー さかぽん
提出日時 2021-01-01 03:01:11
言語 C#(csc)
(csc 3.9.0)
結果
WA  
実行時間 -
コード長 31,460 bytes
コンパイル時間 1,431 ms
コンパイル使用メモリ 126,276 KB
実行使用メモリ 102,132 KB
最終ジャッジ日時 2024-10-10 05:20:15
合計ジャッジ時間 28,680 ms
ジャッジサーバーID
(参考情報)
judge5 / judge3
このコードへのチャレンジ
(要ログイン)
ファイルパターン 結果
sample AC * 2 WA * 1
other AC * 27 WA * 32
権限があれば一括ダウンロードができます
コンパイルメッセージ
Microsoft (R) Visual C# Compiler version 3.9.0-6.21124.20 (db94f4cc)
Copyright (C) Microsoft Corporation. All rights reserved.

ソースコード

diff #
プレゼンテーションモードにする

using System;
using System.Collections.Generic;
using System.Linq;
using Bang.Graphs.Spp;
class T
{
static int[] Read() => Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
static void Main()
{
var z = Read();
var (h, w) = (z[0], z[1]);
var sv = new Point(z[2], z[3]) - (1, 1);
var ev = new Point(z[4], z[5]) - (1, 1);
var s = GraphConsole.ReadGrid(h);
var factory = ShortestPath.ForGrid(h, w);
var r = Bfs(factory, v => Array.FindAll(v.Nexts(), nv => s.GetValue(nv) != '#'), sv, ev);
Console.WriteLine(r);
}
static long Bfs<TVertex>(SppFactory<TVertex> factory, Func<TVertex, TVertex[]> nextVertexesMap, TVertex startVertex, TVertex endVertex)
{
Func<TVertex, TVertex, bool> TEquals = EqualityComparer<TVertex>.Default.Equals;
var costs = factory.CreateMap(long.MaxValue);
var costs2 = factory.CreateMap(long.MaxValue);
var inVertexes = factory.CreateMap(factory.Invalid);
var q = new Queue<TVertex>();
costs[startVertex] = 0;
q.Enqueue(startVertex);
while (q.Count > 0)
{
var v = q.Dequeue();
var nc = costs[v] + 1;
foreach (var nv in nextVertexesMap(v))
{
if (costs[nv] <= nc)
{
//if (TEquals(inVertexes[v], nv)) continue;
costs2[nv] = Math.Min(costs2[nv], nc);
}
else
{
costs[nv] = nc;
inVertexes[nv] = v;
if (TEquals(nv, endVertex)) continue;
q.Enqueue(nv);
}
}
}
if (costs[endVertex] == long.MaxValue) return -1;
var path = new Stack<TVertex>();
for (var v = endVertex; !TEquals(v, factory.Invalid); v = inVertexes[v])
path.Push(v);
var others = path.Where(v => costs2[v] != long.MaxValue).ToArray();
if (others.Length == 0) return -1;
return 2 * costs[endVertex] + others.Min(v => costs2[v] - costs[v]);
}
}
namespace Bang.Graphs.Spp
{
/// <summary>
/// <see cref="SppFactory{TVertex}"/>
/// </summary>
public static class ShortestPath
{
/// <summary>
/// 使<br/>
/// [0, <paramref name="vertexesCount"/>)
/// </summary>
/// <param name="vertexesCount"></param>
/// <returns> Factory </returns>
/// <example>
/// Dijkstra:
/// <code>
/// var r = ShortestPath.ForInt(n)
/// .ForWeightedMap(es, true)
/// .Dijkstra(sv, ev);
/// </code>
/// </example>
public static IntSppFactory ForInt(int vertexesCount) => new IntSppFactory(vertexesCount);
/// <summary>
/// 2 使
/// </summary>
/// <param name="height"></param>
/// <param name="width"></param>
/// <returns>2 Factory </returns>
/// <example>
/// BFS:
/// <code>
/// var r = ShortestPath.ForGrid(h, w)
/// .ForUnweightedMap(v => Array.FindAll(v.Nexts(), nv => s.GetValue(nv) != '#'))
/// .Bfs(sv, ev);
/// </code>
/// </example>
public static GridSppFactory ForGrid(int height, int width) => new GridSppFactory(height, width);
/// <summary>
/// 使<br/>
/// [0, <paramref name="vertexesCount"/>)
/// </summary>
/// <typeparam name="TVertex"></typeparam>
/// <param name="vertexesCount"></param>
/// <param name="toHash"></param>
/// <param name="invalid"></param>
/// <returns>使 Factory </returns>
/// <example>
/// BFS:
/// <code>
/// var r = ShortestPath.ForHash(h * w, GridHelper.CreateToHash(w), (-1, -1))
/// .ForUnweightedMap(v => Array.FindAll(v.Nexts(), nv => s.GetValue(nv) != '#'))
/// .Bfs(sv, ev);
/// </code>
/// </example>
public static HashSppFactory<TVertex> ForHash<TVertex>(int vertexesCount, Func<TVertex, int> toHash, TVertex invalid) => new HashSppFactory
            <TVertex>(vertexesCount, toHash, invalid);
}
/// <summary>
///
/// </summary>
/// <typeparam name="TVertex"></typeparam>
public abstract class SppFactory<TVertex>
{
public abstract TVertex Invalid { get; }
public abstract Map<TVertex, TValue> CreateMap<TValue>(TValue iv);
public abstract ListMap<TVertex, TValue> CreateListMap<TValue>();
/// <summary>
///
/// </summary>
/// <param name="getNextVertexes"></param>
/// <returns></returns>
public UnweightedFuncMapSpp<TVertex> ForUnweightedMap(Func<TVertex, TVertex[]> getNextVertexes)
{
var map = new FuncReadOnlyMap<TVertex, TVertex[]>(getNextVertexes);
return new UnweightedFuncMapSpp<TVertex>(this, map);
}
/// <summary>
///
/// </summary>
/// <param name="getNextEdges"></param>
/// <returns></returns>
public WeightedFuncMapSpp<TVertex> ForWeightedMap(Func<TVertex, Edge<TVertex>[]> getNextEdges)
{
var map = new FuncReadOnlyMap<TVertex, Edge<TVertex>[]>(getNextEdges);
return new WeightedFuncMapSpp<TVertex>(this, map);
}
public UnweightedListMapSpp<TVertex> ForUnweightedMap()
{
var map = CreateListMap<TVertex>();
return new UnweightedListMapSpp<TVertex>(this, map);
}
public WeightedListMapSpp<TVertex> ForWeightedMap()
{
var map = CreateListMap<Edge<TVertex>>();
return new WeightedListMapSpp<TVertex>(this, map);
}
/// <summary>
///
/// </summary>
/// <param name="edges"></param>
/// <param name="directed"></param>
/// <returns></returns>
public UnweightedListMapSpp<TVertex> ForUnweightedMap(Edge<TVertex>[] edges, bool directed)
{
var map = CreateListMap<TVertex>();
GraphConvert.UnweightedEdgesToMap(map, edges, directed);
return new UnweightedListMapSpp<TVertex>(this, map);
}
/// <summary>
///
/// </summary>
/// <param name="edges"></param>
/// <param name="directed"></param>
/// <returns></returns>
public WeightedListMapSpp<TVertex> ForWeightedMap(Edge<TVertex>[] edges, bool directed)
{
var map = CreateListMap<Edge<TVertex>>();
GraphConvert.WeightedEdgesToMap(map, edges, directed);
return new WeightedListMapSpp<TVertex>(this, map);
}
}
public class IntSppFactory : SppFactory<int>
{
public int VertexesCount { get; }
public IntSppFactory(int vertexesCount)
{
VertexesCount = vertexesCount;
}
public override int Invalid => -1;
public override Map<int, TValue> CreateMap<TValue>(TValue iv)
{
return new IntMap<TValue>(VertexesCount, iv);
}
public override ListMap<int, TValue> CreateListMap<TValue>()
{
return new IntListMap<TValue>(VertexesCount);
}
public UnweightedListMapSpp<int> ForUnweightedMap(int[][] edges, bool directed)
{
return ForUnweightedMap(Array.ConvertAll(edges, EdgeHelper.ToEdge), directed);
}
public WeightedListMapSpp<int> ForWeightedMap(int[][] edges, bool directed)
{
return ForWeightedMap(Array.ConvertAll(edges, EdgeHelper.ToEdge), directed);
}
}
public class GridSppFactory : SppFactory<Point>
{
public int Height { get; }
public int Width { get; }
public GridSppFactory(int height, int width)
{
Height = height;
Width = width;
}
public override Point Invalid => (-1, -1);
public override Map<Point, TValue> CreateMap<TValue>(TValue iv)
{
return new GridMap<TValue>(Height, Width, iv);
}
public override ListMap<Point, TValue> CreateListMap<TValue>()
{
return new GridListMap<TValue>(Height, Width);
}
}
public class HashSppFactory<TVertex> : SppFactory<TVertex>
{
public int VertexesCount { get; }
public Func<TVertex, int> ToHash { get; }
public HashSppFactory(int vertexesCount, Func<TVertex, int> toHash, TVertex invalid)
{
VertexesCount = vertexesCount;
ToHash = toHash;
Invalid = invalid;
}
public override TVertex Invalid { get; }
public override Map<TVertex, TValue> CreateMap<TValue>(TValue iv)
{
return new HashMap<TVertex, TValue>(VertexesCount, iv, ToHash);
}
public override ListMap<TVertex, TValue> CreateListMap<TValue>()
{
return new HashListMap<TVertex, TValue>(VertexesCount, ToHash);
}
}
public abstract class UnweightedMapSpp<TVertex>
{
static readonly Func<TVertex, TVertex, bool> TEquals = EqualityComparer<TVertex>.Default.Equals;
public SppFactory<TVertex> Factory { get; }
public abstract ReadOnlyMap<TVertex, TVertex[]> NextVertexesMap { get; }
protected UnweightedMapSpp(SppFactory<TVertex> factory)
{
Factory = factory;
}
public TVertex StartVertex { get; private set; }
public TVertex EndVertex { get; private set; }
public Map<TVertex, long> Costs { get; private set; }
public Map<TVertex, TVertex> InVertexes { get; private set; }
public long this[TVertex vertex] => Costs[vertex];
public bool IsConnected(TVertex vertex) => Costs[vertex] != long.MaxValue;
/// <summary>
/// <br/>
/// 1
/// </summary>
/// <param name="startVertex"></param>
/// <param name="endVertex"><c>Factory.Invalid</c></param>
/// <returns></returns>
/// <remarks>
///
/// </remarks>
public UnweightedMapSpp<TVertex> Bfs(TVertex startVertex, TVertex endVertex)
{
StartVertex = startVertex;
EndVertex = endVertex;
Costs = Factory.CreateMap(long.MaxValue);
InVertexes = Factory.CreateMap(Factory.Invalid);
var q = new Queue<TVertex>();
Costs[startVertex] = 0;
q.Enqueue(startVertex);
while (q.Count > 0)
{
var v = q.Dequeue();
var nc = Costs[v] + 1;
foreach (var nv in NextVertexesMap[v])
{
if (Costs[nv] <= nc) continue;
Costs[nv] = nc;
InVertexes[nv] = v;
if (TEquals(nv, endVertex)) return this;
q.Enqueue(nv);
}
}
return this;
}
public TVertex[] GetPathVertexes(TVertex endVertex)
{
if (InVertexes == null) throw new InvalidOperationException("No Result.");
var path = new Stack<TVertex>();
for (var v = endVertex; !TEquals(v, Factory.Invalid); v = InVertexes[v])
path.Push(v);
return path.ToArray();
}
}
public class UnweightedFuncMapSpp<TVertex> : UnweightedMapSpp<TVertex>
{
public override ReadOnlyMap<TVertex, TVertex[]> NextVertexesMap { get; }
public UnweightedFuncMapSpp(SppFactory<TVertex> factory, FuncReadOnlyMap<TVertex, TVertex[]> nextVertexesMap) : base(factory)
{
NextVertexesMap = nextVertexesMap;
}
}
public class UnweightedListMapSpp<TVertex> : UnweightedMapSpp<TVertex>
{
ListMap<TVertex, TVertex> map;
public override ReadOnlyMap<TVertex, TVertex[]> NextVertexesMap => map;
public UnweightedListMapSpp(SppFactory<TVertex> factory, ListMap<TVertex, TVertex> nextVertexesMap) : base(factory)
{
map = nextVertexesMap;
}
public void AddEdge(Edge<TVertex> edge, bool directed)
{
map.Add(edge.From, edge.To);
if (!directed) map.Add(edge.To, edge.From);
}
public void AddEdge(TVertex from, TVertex to, bool directed)
{
map.Add(from, to);
if (!directed) map.Add(to, from);
}
}
public abstract class WeightedMapSpp<TVertex>
{
static readonly Func<TVertex, TVertex, bool> TEquals = EqualityComparer<TVertex>.Default.Equals;
public SppFactory<TVertex> Factory { get; }
public abstract ReadOnlyMap<TVertex, Edge<TVertex>[]> NextEdgesMap { get; }
protected WeightedMapSpp(SppFactory<TVertex> factory)
{
Factory = factory;
}
public TVertex StartVertex { get; private set; }
public TVertex EndVertex { get; private set; }
public Map<TVertex, long> Costs { get; private set; }
public Map<TVertex, Edge<TVertex>> InEdges { get; private set; }
public long this[TVertex vertex] => Costs[vertex];
public bool IsConnected(TVertex vertex) => Costs[vertex] != long.MaxValue;
/// <summary>
/// Dijkstra <br/>
///
/// </summary>
/// <param name="startVertex"></param>
/// <param name="endVertex"><c>Factory.Invalid</c></param>
/// <returns></returns>
/// <remarks>
///
/// </remarks>
public WeightedMapSpp<TVertex> Dijkstra(TVertex startVertex, TVertex endVertex)
{
StartVertex = startVertex;
EndVertex = endVertex;
Costs = Factory.CreateMap(long.MaxValue);
InEdges = Factory.CreateMap(new Edge<TVertex>(Factory.Invalid, Factory.Invalid, long.MinValue));
var q = PriorityQueue<TVertex>.CreateWithKey(v => Costs[v]);
Costs[startVertex] = 0;
q.Push(startVertex);
while (q.Any)
{
var (v, c) = q.Pop();
if (TEquals(v, endVertex)) break;
if (Costs[v] < c) continue;
// IEnumerable<T>, List<T>, T[]
foreach (var e in NextEdgesMap[v])
{
var (nv, nc) = (e.To, c + e.Cost);
if (Costs[nv] <= nc) continue;
Costs[nv] = nc;
InEdges[nv] = e;
q.Push(nv);
}
}
return this;
}
/// <summary>
/// <br/>
/// <paramref name="m"/> = 3 012-BFS <br/>
/// [0, <paramref name="m"/>)
/// </summary>
/// <param name="m"></param>
/// <param name="startVertex"></param>
/// <param name="endVertex"><c>Factory.Invalid</c></param>
/// <returns></returns>
/// <remarks>
///
/// </remarks>
public WeightedMapSpp<TVertex> BfsMod(int m, TVertex startVertex, TVertex endVertex)
{
StartVertex = startVertex;
EndVertex = endVertex;
Costs = Factory.CreateMap(long.MaxValue);
InEdges = Factory.CreateMap(new Edge<TVertex>(Factory.Invalid, Factory.Invalid, long.MinValue));
var qs = Array.ConvertAll(new bool[m], _ => new Queue<TVertex>());
Costs[startVertex] = 0;
qs[0].Enqueue(startVertex);
for (long c = 0; Array.Exists(qs, q => q.Count > 0); ++c)
{
var q = qs[c % m];
while (q.Count > 0)
{
var v = q.Dequeue();
if (TEquals(v, endVertex)) return this;
if (Costs[v] < c) continue;
foreach (var e in NextEdgesMap[v])
{
var (nv, nc) = (e.To, c + e.Cost);
if (Costs[nv] <= nc) continue;
Costs[nv] = nc;
InEdges[nv] = e;
qs[nc % m].Enqueue(nv);
}
}
}
return this;
}
public TVertex[] GetPathVertexes(TVertex endVertex)
{
if (InEdges == null) throw new InvalidOperationException("No Result.");
var path = new Stack<TVertex>();
for (var v = endVertex; !TEquals(v, Factory.Invalid); v = InEdges[v].From)
path.Push(v);
return path.ToArray();
}
public Edge<TVertex>[] GetPathEdges(TVertex endVertex)
{
if (InEdges == null) throw new InvalidOperationException("No Result.");
var path = new Stack<Edge<TVertex>>();
for (var e = InEdges[endVertex]; !TEquals(e.From, Factory.Invalid); e = InEdges[e.From])
path.Push(e);
return path.ToArray();
}
}
public class WeightedFuncMapSpp<TVertex> : WeightedMapSpp<TVertex>
{
public override ReadOnlyMap<TVertex, Edge<TVertex>[]> NextEdgesMap { get; }
public WeightedFuncMapSpp(SppFactory<TVertex> factory, FuncReadOnlyMap<TVertex, Edge<TVertex>[]> nextEdgesMap) : base(factory)
{
NextEdgesMap = nextEdgesMap;
}
}
public class WeightedListMapSpp<TVertex> : WeightedMapSpp<TVertex>
{
ListMap<TVertex, Edge<TVertex>> map;
public override ReadOnlyMap<TVertex, Edge<TVertex>[]> NextEdgesMap => map;
public WeightedListMapSpp(SppFactory<TVertex> factory, ListMap<TVertex, Edge<TVertex>> nextEdgesMap) : base(factory)
{
map = nextEdgesMap;
}
public void AddEdge(Edge<TVertex> edge, bool directed)
{
map.Add(edge.From, edge);
if (!directed) map.Add(edge.To, edge.Reverse());
}
public void AddEdge(TVertex from, TVertex to, long cost, bool directed)
{
map.Add(from, new Edge<TVertex>(from, to, cost));
if (!directed) map.Add(to, new Edge<TVertex>(to, from, cost));
}
}
public struct Point : IEquatable<Point>
{
public int i, j;
public Point(int i, int j) { this.i = i; this.j = j; }
public void Deconstruct(out int i, out int j) { i = this.i; j = this.j; }
public override string ToString() => $"{i} {j}";
public static Point Parse(string s) => Array.ConvertAll(s.Split(), int.Parse);
public static implicit operator Point(int[] v) => (v[0], v[1]);
public static explicit operator int[](Point v) => new[] { v.i, v.j };
public static implicit operator Point((int i, int j) v) => new Point(v.i, v.j);
public static explicit operator (int, int)(Point v) => (v.i, v.j);
public bool Equals(Point other) => i == other.i && j == other.j;
public static bool operator ==(Point v1, Point v2) => v1.Equals(v2);
public static bool operator !=(Point v1, Point v2) => !v1.Equals(v2);
public override bool Equals(object obj) => obj is Point v && Equals(v);
public override int GetHashCode() => (i, j).GetHashCode();
public static Point operator -(Point v) => new Point(-v.i, -v.j);
public static Point operator +(Point v1, Point v2) => new Point(v1.i + v2.i, v1.j + v2.j);
public static Point operator -(Point v1, Point v2) => new Point(v1.i - v2.i, v1.j - v2.j);
public bool IsInRange(int height, int width) => 0 <= i && i < height && 0 <= j && j < width;
public Point[] Nexts() => new[] { new Point(i - 1, j), new Point(i + 1, j), new Point(i, j - 1), new Point(i, j + 1) };
public static Point[] NextsByDelta { get; } = new[] { new Point(-1, 0), new Point(1, 0), new Point(0, -1), new Point(0, 1) };
public int NormL1 => Math.Abs(i) + Math.Abs(j);
public double Norm => Math.Sqrt(i * i + j * j);
}
public struct Edge<T>
{
public T From { get; }
public T To { get; }
public long Cost { get; }
public Edge(T from, T to, long cost = 1) { From = from; To = to; Cost = cost; }
public override string ToString() => $"{{{From}}} {{{To}}} {Cost}";
public static implicit operator Edge<T>((T from, T to) v) => new Edge<T>(v.from, v.to);
public static implicit operator Edge<T>((T from, T to, long cost) v) => new Edge<T>(v.from, v.to, v.cost);
public Edge<T> Reverse() => new Edge<T>(To, From, Cost);
}
public static class EdgeHelper
{
public static Edge<int> ToEdge(int[] e) => new Edge<int>(e[0], e[1], e.Length > 2 ? e[2] : 1);
public static Edge<int> ToEdge(long[] e) => new Edge<int>((int)e[0], (int)e[1], e.Length > 2 ? e[2] : 1);
}
public abstract class Map<TKey, TValue>
{
public abstract TValue this[TKey key] { get; set; }
}
public abstract class ReadOnlyMap<TKey, TValue>
{
public abstract TValue this[TKey key] { get; }
}
public abstract class ListMap<TKey, TValue> : ReadOnlyMap<TKey, TValue[]>
{
public abstract void Add(TKey key, TValue value);
}
public class IntMap<TValue> : Map<int, TValue>
{
TValue[] a;
public IntMap(int count, TValue iv)
{
a = Array.ConvertAll(new bool[count], _ => iv);
}
public override TValue this[int key] { get => a[key]; set => a[key] = value; }
}
public class GridMap<TValue> : Map<Point, TValue>
{
TValue[][] a;
public GridMap(int height, int width, TValue iv)
{
a = Array.ConvertAll(new bool[height], _ => Array.ConvertAll(new bool[width], __ => iv));
}
public override TValue this[Point key] { get => a[key.i][key.j]; set => a[key.i][key.j] = value; }
}
public class HashMap<TKey, TValue> : Map<TKey, TValue>
{
TValue[] a;
Func<TKey, int> ToHash;
public HashMap(int count, TValue iv, Func<TKey, int> toHash)
{
a = Array.ConvertAll(new bool[count], _ => iv);
ToHash = toHash;
}
public override TValue this[TKey key] { get => a[ToHash(key)]; set => a[ToHash(key)] = value; }
}
public class FuncReadOnlyMap<TKey, TValue> : ReadOnlyMap<TKey, TValue>
{
Func<TKey, TValue> GetValue;
public FuncReadOnlyMap(Func<TKey, TValue> getValue)
{
GetValue = getValue;
}
public override TValue this[TKey key] => GetValue(key);
}
public class IntListMap<TValue> : ListMap<int, TValue>
{
List<TValue>[] map;
public IntListMap(int count)
{
map = Array.ConvertAll(new bool[count], _ => new List<TValue>());
}
public override TValue[] this[int key] => map[key].ToArray();
public override void Add(int key, TValue value) => map[key].Add(value);
}
public class GridListMap<TValue> : ListMap<Point, TValue>
{
List<TValue>[][] map;
public GridListMap(int height, int width)
{
map = Array.ConvertAll(new bool[height], _ => Array.ConvertAll(new bool[width], __ => new List<TValue>()));
}
public override TValue[] this[Point key] => map[key.i][key.j].ToArray();
public override void Add(Point key, TValue value) => map[key.i][key.j].Add(value);
}
public class HashListMap<TKey, TValue> : ListMap<TKey, TValue>
{
List<TValue>[] map;
Func<TKey, int> ToHash;
public HashListMap(int count, Func<TKey, int> toHash)
{
map = Array.ConvertAll(new bool[count], _ => new List<TValue>());
ToHash = toHash;
}
public override TValue[] this[TKey key] => map[ToHash(key)].ToArray();
public override void Add(TKey key, TValue value) => map[ToHash(key)].Add(value);
}
public static class GraphConsole
{
const char Road = '.';
const char Wall = '#';
static int[] Read() => Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
public static Point ReadPoint()
{
return Point.Parse(Console.ReadLine());
}
public static Edge<int>[] ReadEdges(int count)
{
return Array.ConvertAll(new bool[count], _ => EdgeHelper.ToEdge(Read()));
}
public static string[] ReadGrid(int height)
{
return Array.ConvertAll(new bool[height], _ => Console.ReadLine());
}
public static char[][] ReadGridAsChar(int height)
{
return Array.ConvertAll(new bool[height], _ => Console.ReadLine().ToCharArray());
}
public static int[][] ReadGridAsInt(int height)
{
return Array.ConvertAll(new bool[height], _ => Read());
}
public static string[] ReadEnclosedGrid(ref int height, ref int width, char c = '#', int delta = 1)
{
var h = height + 2 * delta;
var w = width + 2 * delta;
var cw = new string(c, w);
var cd = new string(c, delta);
var s = new string[h];
for (int i = 0; i < delta; ++i) s[delta + height + i] = s[i] = cw;
for (int i = 0; i < height; ++i) s[delta + i] = cd + Console.ReadLine() + cd;
(height, width) = (h, w);
return s;
}
}
public static class GraphConvert
{
public static void UnweightedEdgesToMap<TVertex>(ListMap<TVertex, TVertex> map, Edge<TVertex>[] edges, bool directed)
{
foreach (var e in edges)
{
map.Add(e.From, e.To);
if (!directed) map.Add(e.To, e.From);
}
}
public static void WeightedEdgesToMap<TVertex>(ListMap<TVertex, Edge<TVertex>> map, Edge<TVertex>[] edges, bool directed)
{
foreach (var e in edges)
{
map.Add(e.From, e);
if (!directed) map.Add(e.To, e.Reverse());
}
}
}
public static class GridHelper
{
public static T GetValue<T>(this T[,] a, Point p) => a[p.i, p.j];
public static void SetValue<T>(this T[,] a, Point p, T value) => a[p.i, p.j] = value;
public static T GetValue<T>(this T[][] a, Point p) => a[p.i][p.j];
public static void SetValue<T>(this T[][] a, Point p, T value) => a[p.i][p.j] = value;
public static char GetValue(this string[] s, Point p) => s[p.i][p.j];
public static Point FindValue<T>(T[][] a, T value)
{
var ec = EqualityComparer<T>.Default;
var (h, w) = (a.Length, a[0].Length);
for (int i = 0; i < h; ++i)
for (int j = 0; j < w; ++j)
if (ec.Equals(a[i][j], value)) return new Point(i, j);
return new Point(-1, -1);
}
public static Point FindValue(string[] s, char c)
{
var (h, w) = (s.Length, s[0].Length);
for (int i = 0; i < h; ++i)
for (int j = 0; j < w; ++j)
if (s[i][j] == c) return new Point(i, j);
return new Point(-1, -1);
}
public static int ToHash(Point p, int width) => p.i * width + p.j;
public static Point FromHash(int hash, int width) => new Point(hash / width, hash % width);
public static Func<Point, int> CreateToHash(int width) => p => p.i * width + p.j;
public static Func<int, Point> CreateFromHash(int width) => hash => new Point(hash / width, hash % width);
public static void EncloseGrid<T>(ref int height, ref int width, ref T[][] a, T value, int delta = 1)
{
var h = height + 2 * delta;
var w = width + 2 * delta;
var t = Array.ConvertAll(new bool[h], _ => Array.ConvertAll(new bool[w], __ => value));
for (int i = 0; i < height; ++i)
for (int j = 0; j < width; ++j)
t[delta + i][delta + j] = a[i][j];
(height, width, a) = (h, w, t);
}
public static void EncloseGrid(ref int height, ref int width, ref string[] s, char c = '#', int delta = 1)
{
var h = height + 2 * delta;
var w = width + 2 * delta;
var cw = new string(c, w);
var cd = new string(c, delta);
var t = new string[h];
for (int i = 0; i < delta; ++i) t[delta + height + i] = t[i] = cw;
for (int i = 0; i < height; ++i) t[delta + i] = cd + s[i] + cd;
(height, width, s) = (h, w, t);
}
public static T[][] Rotate180<T>(T[][] a)
{
var (h, w) = (a.Length, a[0].Length);
var r = Array.ConvertAll(new bool[h], _ => new T[w]);
for (int i = 0; i < h; ++i)
for (int j = 0; j < w; ++j)
r[i][j] = a[h - 1 - i][w - 1 - j];
return r;
}
public static T[][] RotateLeft<T>(T[][] a)
{
var (h, w) = (a.Length, a[0].Length);
var r = Array.ConvertAll(new bool[w], _ => new T[h]);
for (int i = 0; i < w; ++i)
for (int j = 0; j < h; ++j)
r[i][j] = a[j][w - 1 - i];
return r;
}
public static T[][] RotateRight<T>(T[][] a)
{
var (h, w) = (a.Length, a[0].Length);
var r = Array.ConvertAll(new bool[w], _ => new T[h]);
for (int i = 0; i < w; ++i)
for (int j = 0; j < h; ++j)
r[i][j] = a[h - 1 - j][i];
return r;
}
public static string[] Rotate180(string[] s)
{
var h = s.Length;
var r = new string[h];
for (int i = 0; i < h; ++i)
{
var cs = s[h - 1 - i].ToCharArray();
Array.Reverse(cs);
r[i] = new string(cs);
}
return r;
}
public static string[] RotateLeft(string[] s)
{
var (h, w) = (s.Length, s[0].Length);
var r = new string[w];
for (int i = 0; i < w; ++i)
{
var cs = new char[h];
for (int j = 0; j < h; ++j)
cs[j] = s[j][w - 1 - i];
r[i] = new string(cs);
}
return r;
}
public static string[] RotateRight(string[] s)
{
var (h, w) = (s.Length, s[0].Length);
var r = new string[w];
for (int i = 0; i < w; ++i)
{
var cs = new char[h];
for (int j = 0; j < h; ++j)
cs[j] = s[h - 1 - j][i];
r[i] = new string(cs);
}
return r;
}
}
/// <summary>
///
/// </summary>
/// <typeparam name="T"></typeparam>
/// <remarks>
/// <br/>
/// 1-indexed raw array 使
/// </remarks>
public class PriorityQueue<T>
{
public static PriorityQueue<T> Create(bool descending = false)
{
var c = Comparer<T>.Default;
return descending ?
new PriorityQueue<T>((x, y) => c.Compare(y, x)) :
new PriorityQueue<T>(c.Compare);
}
public static PriorityQueue<T> Create<TKey>(Func<T, TKey> keySelector, bool descending = false)
{
if (keySelector == null) throw new ArgumentNullException(nameof(keySelector));
var c = Comparer<TKey>.Default;
return descending ?
new PriorityQueue<T>((x, y) => c.Compare(keySelector(y), keySelector(x))) :
new PriorityQueue<T>((x, y) => c.Compare(keySelector(x), keySelector(y)));
}
public static PriorityQueue<T, TKey> CreateWithKey<TKey>(Func<T, TKey> keySelector, bool descending = false)
{
var c = Comparer<TKey>.Default;
return descending ?
new PriorityQueue<T, TKey>(keySelector, (x, y) => c.Compare(y.key, x.key)) :
new PriorityQueue<T, TKey>(keySelector, (x, y) => c.Compare(x.key, y.key));
}
List<T> l = new List<T> { default };
Comparison<T> c;
public T First
{
get
{
if (l.Count <= 1) throw new InvalidOperationException("The heap is empty.");
return l[1];
}
}
public int Count => l.Count - 1;
public bool Any => l.Count > 1;
internal PriorityQueue(Comparison<T> comparison)
{
c = comparison ?? throw new ArgumentNullException(nameof(comparison));
}
// x : x/2
// x : 2x, 2x+1
void UpHeap(int i)
{
for (int j; (j = i >> 1) > 0 && c(l[j], l[i]) > 0; i = j)
(l[i], l[j]) = (l[j], l[i]);
}
void DownHeap(int i)
{
for (int j; (j = i << 1) < l.Count; i = j)
{
if (j + 1 < l.Count && c(l[j], l[j + 1]) > 0) j++;
if (c(l[i], l[j]) > 0) (l[i], l[j]) = (l[j], l[i]); else break;
}
}
public void Push(T value)
{
l.Add(value);
UpHeap(l.Count - 1);
}
public void PushRange(IEnumerable<T> values)
{
if (values != null) foreach (var v in values) Push(v);
}
public T Pop()
{
if (l.Count <= 1) throw new InvalidOperationException("The heap is empty.");
var r = l[1];
l[1] = l[l.Count - 1];
l.RemoveAt(l.Count - 1);
DownHeap(1);
return r;
}
}
//
public class PriorityQueue<T, TKey> : PriorityQueue<(T value, TKey key)>
{
Func<T, TKey> KeySelector;
internal PriorityQueue(Func<T, TKey> keySelector, Comparison<(T value, TKey key)> comparison) : base(comparison)
{
KeySelector = keySelector ?? throw new ArgumentNullException(nameof(keySelector));
}
public void Push(T value)
{
Push((value, KeySelector(value)));
}
public void PushRange(IEnumerable<T> values)
{
if (values != null) foreach (var v in values) Push(v);
}
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
0