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: Wrong Answer)

import java.util.*;

class Main{

    int h, w, n;
    char[][] board;
    String[] s;
    boolean change;

    void solve(){
        Scanner sc = new Scanner (System.in);

        h = sc.nextInt();
        w = sc.nextInt();
        n = sc.nextInt();

        s = new String[h];
        board = new char[h][w];
        for(int i=0; i<h; i++) s[i] = sc.next();

        boolean cake = true;
        for(int i=0; i<h; i++){
            for(int j=0; j<w-1; j++){
                board = new char[h][w];
                for(int l=0; l<h; l++) board[l] = s[l].toCharArray();
                             
                char tmp = board[i][j];
                board[i][j] = board[i][j+1];
                board[i][j+1] = tmp;
        
                cake();

                cake = true;
                for(int k=0; k<h; k++){
                    for(int l=0; l<w; l++){
                        if(board[k][l]!='.'){
                            cake = false;
                            break;
                        }
                    }
                    if(!cake) break;
                }
                if(cake) break;
            }
            if(cake) break;
        }

        if(cake) System.out.println("YES");
        else System.out.println("NO");
    }

    void cake(){

        change = false;
        for(int i=0; i<h; i++){
            for(int j=0; j<w; j++){
                if(board[i][j]!='.'){
                    bfs(i, j); 
                    delete();
                }
            }
        }

        if(change){
            change = false;
            cake();
        }
    }

    void delete(){
        int st = 0, go = 0;
        for(int k=0; k<h; k++){
            while(st<w && board[k][st]!='1') st++;
            if(st==w) break;
            go = st;
            while(go+1<w && board[k][go+1]=='1') go++;
            if(go-st>=n){
                change = true;
                for(int l=st; l<=go; l++) board[k][l] = '2';
            }
        }
        
        st = 0; go = 0;
        for(int k=0; k<w; k++){
            while(st<h && !(board[st][k]=='1' || board[st][k]=='2')) st++;
            if(st==h) break;
            go = st;
            while(go+1<h && (board[go+1][k]=='1' || board[go+1][k]=='2')) go++;
            if(go-st>=n){
                change = true;
                for(int l=st; l<=go; l++) board[l][k] = '2';
            }
        }
        
        LinkedList<Character> list = new LinkedList<Character>();
        for(int k=0; k<w; k++){
            for(int l=h-1; l>=0; l--){
                if(board[l][k]=='2' || board[l][k]=='.') list.add('.');
                else if(board[l][k]=='1'){
                    board[l][k] = s[l].charAt(k);
                    list.addFirst(board[l][k]);
                }else list.addFirst(board[l][k]);
            }
            for(int l=0; l<h; l++) board[l][k] = list.pollFirst();
        }
    }
    
    int[] dx = {0, 0, 1, -1};
    int[] dy = {1, -1, 0, 0};

    void bfs(int y, int x){
        Queue<int[]> q = new LinkedList<int[]>();
        q.add(new int[]{y, x});
        boolean[][] v = new boolean[h][w];
        while(q.size()>0){
            int[] pp = q.poll();
            int yy = pp[0], xx = pp[1];

            if(v[yy][xx]) continue;
            v[yy][xx] = true;

            for(int i=0; i<4; i++){
                int ny = yy + dy[i], nx = xx + dx[i];
                if(ny<0 || ny>=h || nx<0 || nx>=w || (ny==y && nx==x)) continue;

                if(board[ny][nx]==board[y][x]){
                    board[ny][nx] = '1';
                    q.add(new int[]{ny, nx});
                }
            }
        }
        board[y][x] = '1';
    }

    public static void main(String[] args){
        new Main().solve();
    }
}