Last active
May 10, 2016 10:37
-
-
Save quangnle/ddf0c4b3cba981f3937a6619d32bcff3 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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