Problem:
Problem A: Ennichi

縁日に来たうさぎが, ある出店のゲームの景品がキャロットケーキであるのを見つけた. このゲームのルールは以下の通りである.

縦h マス× 横w マスの格子状のフィールドがあり, 各マスにつき高々1 個のブロックが置かれる. 各ブロックにはアルファベット大文字(‘A’ - ‘Z’) のいずれかで表される色がついている. 同色のブロックが縦または横に一直線上にn 個以上連続して並ぶと, それらのブロックは消滅する.

参加者は横に隣り合う2 つのマスを選んで, それらの状態を互いに入れ替える操作ができる. ブロックの入れ替え, 消滅, 落下によってブロックの有るマスの1 つ下のマスにブロックが無くなると, このブロックは落下する. このときふたたび同色のブロックがn 個以上並ぶと消滅する. ただし, ブロックの消滅は, 落下するブロックが存在する間は起こらず, すべてのブロックの落下が終了したタイミングで同時に起こる.

1 回の操作でフィールド上のすべてのブロックを消滅させると, このゲームは成功となり景品のケーキを得ることができる. うさぎは1 回分の参加費で確実にケーキを手に入れたく, それができない場合は参加したくない. ゲーム開始時のフィールドの状態から, うさぎがこのゲームに参加すべきであるか答えよ.

Input

入力の一行目にはh, w, n がスペースで区切られて与えられる.

2 ≤ h,w, n ≤ 30

続くh 行にはフィールドの状態が上から順に与えられる. アルファベット大文字はブロックを, ‘.’ は空きマスを表す. 与えられるフィールドの状態には, 縦あるいは横にn 個以上連続する同色のブロックはなく, 落下する状態にあるブロックもない. 1 個以上のブロックが存在する.

Output

うさぎがこのゲームに参加すべきであるなら”YES”を, そうでないなら”NO”を一行に出力せよ.

Sample Input 1

4 6 3
......
...Y..
...Y..
RRYRYY

Sample Output 2

YES

Sample Input 1

4 6 3
......
...Y..
...Y..
RRYRY.

Sample Output 2

NO

Solution in JAVA (judge verdict: Accepted)


import java.util.*;

import static java.lang.System.*;

class Main {
	public static Scanner sc = new Scanner(in);
	public static Random rand=new Random();

	public void fall(char[][] tmp){
		for(int x=0;x<w;x++)
			for(int y=h-1;y>=0;y--)if(tmp[y][x]=='.')
				for(int dy=y-1;dy>=0;dy--)if(tmp[dy][x]!='.'){
					tmp[y][x]=tmp[dy][x];
					tmp[dy][x]='.';
					break;
				}
	}
	public boolean check(char[][] tmp){
		boolean change=true;
		while(change){
			change=false;
			fall(tmp);
			boolean[][] dels=new boolean[h][w];
			for(int y=0;y<h;y++)for(int x=0;x<w;x++){
				for(int i=0;i<4;i++){
					int px=x,py=y;
					char s=tmp[py][px];
					if(s=='.')continue;
					int l=1;
					px+=d[i][0];
					py+=d[i][1];
					//連結数
					while((0<=px && px < w && 0<=py && py<h)
								&& tmp[py][px]==s){
						l++;
						px+=d[i][0];
						py+=d[i][1];
					}
					if(l>=n){
						//back
						px-=d[i][0];
						py-=d[i][1];
						while(!(px==x && py ==y)){
							dels[py][px]=true;
							px-=d[i][0];
							py-=d[i][1];
						}
						dels[py][px]=true;
					}
				}
			}
			for(int y=0;y<h;y++)for(int x=0;x<w;x++){
				if(dels[y][x]){
					tmp[y][x]='.';
					change=true;
				}
			}
		}
		for(int y=0;y<h;y++)for(int x=0;x<w;x++){
			if(tmp[y][x]!='.')return false;
		}
		return true;

	}

	int h,w,n;
	int[][] d=new int[][]{{1,0},{0,1},{-1,0},{0,-1}};

	public void run() {
		h=sc.nextInt();
		w=sc.nextInt();
		n=sc.nextInt();

		char[][] map=new char[h][w];
		char[][] tmp=new char[h][w];
		for(int i=0;i<h;i++){
			map[i]=sc.next().toCharArray();
		}
		for(int y=0;y<h;y++)for(int x=0;x<w;x++)for(int i=0;i<4;i+=2){//0,2
			for(int dy=0;dy<h;dy++)for(int dx=0;dx<w;dx++)
				tmp[dy][dx]=map[dy][dx];

			int px=x+d[i][0];
			int py=y+d[i][1];
			if(0<=px && px<w && 0<=py && py<h
				&& tmp[py][px]!=tmp[y][x]){
				char tm=tmp[py][px];
				tmp[py][px]=tmp[y][x];
				tmp[y][x]=tm;
				if(check(tmp)){
					ln("YES");
					return;
				}
			}
		}
		ln("NO");
	}
	public static void main(String[] args) {
		new Main().run();
	}

	public int[] nextIntArray(int n){
		int[] res=new int[n];
		for(int i=0;i<n;i++){
			res[i]=sc.nextInt();
		}
		return res;
	}
	public static void pr(Object o) {
		out.print(o);
	}
	public static void ln(Object o) {
		out.println(o);
	}
	public static void ln() {
		out.println();
	}
}