Skip to content

Instantly share code, notes, and snippets.

@quangnle
Last active May 10, 2016 10:37
Show Gist options
  • Save quangnle/ddf0c4b3cba981f3937a6619d32bcff3 to your computer and use it in GitHub Desktop.
Save quangnle/ddf0c4b3cba981f3937a6619d32bcff3 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Tuenti14
{
class Block
{
public int Row { get; set; }
public int Col { get; set; }
public int Val { get; set; }
public char BlkType { get; set; }
public int Distant { get; set; }
public Block(char type, int row, int col)
{
BlkType = type;
Row = row;
Col = col;
}
}
class Map
{
public Block[,] Blocks { get; set; }
public int Width { get; set; }
public int Height { get; set; }
public Map(Block[,] blocks, int width, int height)
{
Blocks = blocks;
Width = width;
Height = height;
}
private bool IsEmpty(char ch)
{
return (ch == '.' || ch == 'K' || ch == 'S' || ch == 'E');
}
public void UpdateValues()
{
for (int row = 0; row < Height; row++)
{
for (int col = 0; col < Width; col++)
{
var b = Blocks[row, col];
if (IsEmpty(b.BlkType))
{
var lb = Blocks[row, ((col + Width) - 1) % Width];
var rb = Blocks[row, (col + 1) % Width];
if (IsEmpty(lb.BlkType)) b.Val = b.Val | 1;
if (IsEmpty(rb.BlkType)) b.Val = b.Val | 4;
if (row - 1 >= 0)
{
var ub = Blocks[row - 1, col];
if (IsEmpty(ub.BlkType))
{
if (row + 1 < Height && (Blocks[row + 1, col].BlkType == 'H' || Blocks[row + 1, col].BlkType == '#'))
b.Val = b.Val | 2;
}
}
if (row + 1 < Height)
{
var db = Blocks[row + 1, col];
if (IsEmpty(db.BlkType)) b.Val = b.Val | 8;
}
}
}
}
}
public void Flood(Block fr)
{
var dx = new int[] {-1, 0, 1, 0};
var dy = new int[] {0, -1, 0, 1};
Queue<Block> pQueue = new Queue<Block>();
Queue<Block> dQueue = new Queue<Block>();
fr.Distant = 0;
pQueue.Enqueue(fr);
while (pQueue.Count != 0)
{
var cBlock = pQueue.Dequeue();
for (int i = 0; i < 4; i++)
{
int nc = (cBlock.Col + dx[i] + Width) % Width;
int nr = cBlock.Row + dy[i];
if (nr >= 0 && nr < Height)
{
var nB = Blocks[nr, nc];
if (nr > cBlock.Row && ((nB.Val & 2) == 2))
{
if (cBlock.Distant + 1 < nB.Distant)
{
pQueue.Enqueue(nB);
nB.Distant += 1;
}
}
else if (nr < cBlock.Row && ((nB.Val & 8) == 8))
{
if (cBlock.Distant + 1 < nB.Distant)
{
pQueue.Enqueue(nB);
nB.Distant += 1;
}
}
else
{
if ((nc == 0 && cBlock.Col == Width - 1) || (nc != 0 && nc == cBlock.Col + 1)) //right
{
if ((nB.Val & 4) == 4 && (cBlock.Distant + 1 < nB.Distant))
{
pQueue.Enqueue(nB);
nB.Distant = 1;
}
}
else if ((nc == Width - 1 && cBlock.Col == 0) || (nc != Width - 1 && nc == cBlock.Col - 1)) // left
{
if (((nB.Val & 1) == 1) && (cBlock.Distant + 1 < nB.Distant))
{
pQueue.Enqueue(nB);
nB.Distant += 1;
}
}
}
}
}
}
}
}
class Program
{
static void Main(string[] args)
{
var lines = File.ReadAllLines("inp.txt");
var nTest = Convert.ToInt32(lines[0]);
var curLine = 1;
for (int i = 0; i < nTest; i++)
{
var hw = lines[curLine];
curLine++;
var height = Convert.ToInt32(hw.Split(' ')[0]);
var width = Convert.ToInt32(hw.Split(' ')[1]);
var map = BuildMap(lines, curLine, height);
curLine += height;
for (int r = 0; r < height; r++)
{
for (int c = 0; c < width; c++)
{
if (map.Blocks[r, c].BlkType == 'S')
map.Flood(map.Blocks[r, c]);
}
}
}
}
private static Map BuildMap(string[] lines, int curLine, int height)
{
var width = lines[curLine].Length;
Block[,] blocks = new Block[height, width];
for (int row = 0; row < height; row++)
{
var l = lines[row + curLine];
for (int col = 0; col < l.Length; col++)
{
blocks[row, col] = new Block(l[col], row, col);
blocks[row, col].Distant = -1;
}
}
var map = new Map(blocks, width, height);
map.UpdateValues();
return map;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment