Problem:
問題文

お菓子の魔女 CHARLOTTE は巴マミとクッキーゲームを楽しんでいる．クッキーゲームは 8\times 8 の格子状に区切られたテーブルクロスの上にチーズクッキーとチョコレートクッキーを置いて行われる．各格子には高々 1 個のチョコレートクッキーまたはチーズクッキーしか置くことはできない．

お菓子の魔女はチーズクッキーを，巴マミはチョコレートクッキーを交互に置いてゲームを行う．自分のクッキーを置いたあと，そのクッキーから上下左右斜めの各 8 方向について，置くクッキーとすでに置いていた自分のクッキーの間に相手のクッキーのみが直線に並んでいた場合に，その挟まれた相手のクッキーのすべてが自分のクッキーで置き換えられる．クッキーゲームのプレイヤーは自分のターンが回ってきた時，1 つ自分のクッキーを置くことができる．ただし，相手のクッキーを少なくとも 1 つ以上自分のクッキーに置き換えられなければならない．そのような置き場がない場合，自分のターンをパスをしなければならない．

お菓子の魔女も巴マミも考えるのが少々苦手である．そこで，回ってきたターン毎にそのターンの中で置き換えられるクッキーの数を最大化することを考えることにした．巴マミのターンのときに置き換えられるクッキーの数を最大にするようなクッキーを置く場所の候補が複数ある場合は，より上の場所を，それでも複数ある場合はより左の場所を選択することにした．また同様に，お菓子の魔女のターンのときに候補が複数ある場合はより下の場所を，それでも複数ある場合はより右の場所を選択することにした．

テーブルクロスに置かれたクッキーの状態が与えられるので，巴マミからはじめ，彼女たちがそこからクッキーゲームを行い，共に新たなクッキーが置けなくなるまでゲームを続けた時のテーブルクロスの上に置かれたクッキーの状態を求めよ．

入力形式

入力は以下の形式で与えられる．

s_{11} s_{12} ... s_{18}\\
s_{21} s_{22} ... s_{28}\\
...\\
s_{81} s_{82} ... s_{88}\\

s_{ij} はテーブルクロスに置かれたクッキーの初期状態を表す文字で，上から i 行目，左から j 列目の格子の状態を表す．チョコレートクッキーが置かれているときs_{ij}は 'o' であり，チーズクッキーが置かれているときは 'x', 何も置かれていないときは '.' となる．

出力形式

クッキーゲームが行われた後のテーブルクロスの上に置かれたクッキーの状態を，入力形式と同じ形式で出力せよ．

制約

s_{ij} は 'o', 'x', '.' のいずれかである．

入出力例

入力例 1

ooox....
.x......
ooo.....
........
........
........
........
........

出力例1

ooooo...
.o......
ooo.....
...o....
....o...
........
........
........

入力例 2

........
........
........
...ox...
...xo...
........
........
........

出力例 2

xxxxxxxx
xxxooxxx
xxxxooxx
xxxxxxxx
ooxxooox
ooxoooox
oxooooox
ooooooox

入力例 3

........
........
..ooo...
..oxo...
..ooo...
........
........
........

出力例 3

........
........
..ooo...
..ooo...
..ooo...
.....o..
......o.
........

Problem Setter: Flat35

Solution in JAVA (judge verdict: Accepted)

import java.util.Scanner;

public class Main {
    static Scanner sc;

    static int[][] map;
    public static void main(String[] args) {
        sc = new Scanner(System.in);

        // ?????????????§???????
        map = new int[8][8];
        String a;
        for (int i=0;i<8;i++) {
            a = GetSubStringLine()[0];
            for (int j=0;j<8;j++) {
                switch (a.charAt(j)) {
                    case 'o':
                        map[i][j] = 1;
                        break;
                    case 'x':
                        map[i][j] = -1;
                        break;
                    case '.':
                        map[i][j] = 0;
                        break;
                }
            }
        }

        int turn = 1;
        int num;
        int stopCnt = 0;
        while (stopCnt < 2) {
            int[][] numMap = new int[8][8];
            boolean flg = false;
            for (int i=0;i<8;i++) {
                for (int j=0;j<8;j++) {
                    if (map[i][j] == 0) {
                        num = GetNum(turn, i, j);
                        if (num > 0) {
                            flg = true;
                        }
                        numMap[i][j] = num;
                    }
                }
            }
            if (flg) {
                stopCnt = 0;
                // ?????§??°????±???????
                int max = 0, mY=0,mX=0;
                if (turn == 1) {
                    for (int i=0;i<8;i++) {
                        for (int j=0;j<8;j++) {
                            if (max < numMap[i][j]) {
                                max = numMap[i][j];
                                mY = i;
                                mX = j;
                            }
                        }
                    }
                } else {
                    for (int i=7;i>=0;i--) {
                        for (int j=7;j>=0;j--) {
                            if (max < numMap[i][j]) {
                                max = numMap[i][j];
                                mY = i;
                                mX = j;
                            }
                        }
                    }
                }
                RevNum(turn, mY, mX);
                map[mY][mX] = turn;
            } else {
                stopCnt++;
            }
            turn *= -1;
        }
        for (int i=0;i<8;i++) {
            for (int j=0;j<8 ;j++) {
                switch (map[i][j]) {
                    case 1:
                        System.out.print('o');
                        break;
                    case -1:
                        System.out.print('x');
                        break;
                    case 0:
                        System.out.print('.');
                        break;
                }
            }
            System.out.println("");
        }
    }

    static public int GetNum(int a, int y, int x) {
        int sum = 0;
        for (int i=-1;i<2;i++) {
            for (int j=-1;j<2;j++) {
                if (i!=0||j!=0) {
                    sum += GetLineNu(a, i, j, y, x);
                }
            }
        }
        return sum;
    }

    static int GetLineNu(int a, int dy, int dx, int y, int x) {
        int sum = 0;
        y+=dy;
        x+=dx;
        for (int cnt=0;cnt<8;cnt++, y+=dy,x+=dx) {
            if (y < 0 || x < 0 || y > 7 || x > 7) {
                return 0;
            }
            if(map[y][x] == -a) {
                sum++;
            } else if (map[y][x] == a) {
                return sum;
            } else {
                return 0;
            }
        }
        return 0;
    }

    static public void RevNum(int a, int y, int x) {
        for (int i=-1;i<2;i++) {
            for (int j=-1;j<2;j++) {
                if (i!=0||j!=0) {
                    RevLineNu(a, i, j, y, x);
                }
            }
        }
    }

    static void RevLineNu(int a, int dy, int dx, int y, int x) {
        int y1 = y, x1 = x;
        y+=dy;
        x+=dx;
        for (int cnt=0;cnt<8;cnt++, y+=dy,x+=dx) {
            if (y < 0 || x < 0 || y > 7 || x > 7) {
                return;
            }
            if(map[y][x] == -a) {
            } else if (map[y][x] == a) {
                break;
            } else {
                return;
            }
        }
        for (int cnt=0;cnt<8;cnt++, y-=dy,x-=dx) {
            if (y == y1 && x == x1) {
                return;
            }
            map[y][x] = a;
        }
    }

    public static String[] GetSubStringLine() {
        String s = sc.nextLine();
        return s.split(" ");
    }
}