Problem:
Problem A: Nasty Boys

Problem

太郎君は学校のロッカーに大事な本を隠しているので他の人よりとても厳重に管理していて、学校で支給された鍵に加えて以下のようなボタン認証式の鍵を設置しています。

ただパスワードを忘れやすい太郎くんはパスワードを一筆書きで書けるものにしてしまう癖があります。更に詰めの甘い太郎君は自分のパスワードを考えるときに候補を紙に書いていました。その紙をたまたま拾ったは次郎君は、性格が悪いので捨てずにロッカーを開けることに挑戦しました。

しかし紙にはなんと1000個ものパスワードの案が書かれており、全ての入力を試すと日が暮れてしまいそうです。
そこで太郎君の癖を知っている次郎君は、調べる回数を減らすために1000個のパスワードの中から一筆書きできるものだけを取り上げることにして、その作業をプログラマーの貴方に頼むことにしました。

1つのデータセットにつき必ず候補は一つ以上存在します。一筆書きのルールを以下に示します。

同じ文字は連続しない。例えばAAAは許されない。

上下左右4方向に一筆書きが可能。斜め方向に移動しない。

ボタン配列の枠外に出て連続することはない。例えばABCAのような移動は許されない。

一度通った文字の上も何度も通過可能。

ボタン1文字のみの入力も一筆書きとみなす。

Input

入力は以下のように1000個の文字列群からなり、各行はAからIまでの1文字以上10文字以下の大文字のアルファベット列である。それぞれ文字列のデータの重複はないものとする。

string1
string2
...
string1000

Output

入力のうち候補となるパスワード（candidatePassword）のみ抜き出して以下のように列挙せよ。なお以下の場合はN個の候補が挙げられている。

candidatePassword1
candidatePassword2
...
candidatePasswordN

出力は入力の文字列の順と同じであり順番を入れ替えてはならない。

Sample Input

ABCFI
ABCABCABC
AEI
EFC
（中略）
DEHED
EEEEE
（以上でちょうど1000個）

Sample Output

ABCFI
EFC
（中略）
DEHED

Solution in C# (judge verdict: Accepted)

using System;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.Linq;


class Template
{
	static Scanner sc;
	static int N = 1000;
	static int M = 3;
	static char[,] lo = { { 'A', 'B', 'C' }, { 'D', 'E', 'F' }, { 'G', 'H', 'I' } };
	static int[] dx = { 1, -1, 0, 0 };
	static int[] dy = { 0, 0, 1, -1 };

	public static void Main(string[] args)
	{
		sc = new Scanner();
		LinkedList<string> ans = new LinkedList<string>();
		for (int i = 0; i < N; i++)
		{
			string s = sc.next();
			if (check(s, 0)) ans.AddLast(s);
		}
		foreach (var el in ans)
		{
			Console.WriteLine(el);
		}
	}

	static bool inside(int x, int y)
	{
		bool res = true;
		if (x < 0 || x >= M) res = false;
		if (y < 0 || y >= M) res = false;
		return res;
	}

	static bool check(string s, int id)
	{
		if (id == s.Length) return true;
		if (id == 0)
		{
			return check(s, 1);
		}
		if (s[id - 1] == s[id]) return false;

		int bx = 0, by = 0;
		for (int i = 0; i < M; i++)
		{
			for (int j = 0; j < M; j++)
			{
				if (s[id - 1] == lo[i, j])
				{
					bx = j; by = i;
					i = M; j = M;
				}
			}
		}

		bool res = false;
		for (int i = 0; i < 4; i++)
		{
			int nex = bx + dx[i];
			int ney = by + dy[i];
			if (!inside(nex, ney)) continue;
			if (lo[ney, nex] == s[id]) res = check(s, id + 1);
		}
		return res;
	}
}

public class Scanner
{
	public Scanner() { }
	public string next()
	{
		return Console.ReadLine();
	}
	public int nextInt()
	{
		return int.Parse(next());
	}
	public double nextDouble()
	{
		return double.Parse(next());
	}
	public long nextLong()
	{
		return long.Parse(next());
	}
	public string[] nextArray()
	{
		return next().Split(' ');
	}
	public int[] nextIntArray()
	{
		return Array.ConvertAll(nextArray(), e => int.Parse(e));
	}
	public long[] nextLongArray()
	{
		return Array.ConvertAll(nextArray(), e => long.Parse(e));
	}
	public double[] nextDoubleArray()
	{
		return Array.ConvertAll(nextArray(), e => double.Parse(e));
	}
}