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.*;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		char[][] field = new char[8][8];
		for (int i = 0; i < 8; i++) {
			String str = sc.next();
			char[] c = str.toCharArray();
			for (int j = 0; j < str.length(); j++) {
				field[i][j] = c[j];
			}
		}
		char turn = 'o';
		int[] result = { 0, 0, 0 };
		boolean opassed = false;
		boolean xpassed = false;
		do {
			Arrays.fill(result, 0);
			char[][] tfield = new char[8][8];
			for (int i = 0; i < 8; i++)
				for (int j = 0; j < 8; j++)
					tfield[i][j] = field[i][j];
			int a = count(field, turn);
			for (int i = 0; i < 8; i++)
				for (int j = 0; j < 8; j++) {
					if (tfield[i][j] == '.')
						move(tfield, turn, i, j);
					int b = count(tfield, turn);
					if (b - a > Math.max(result[0], 1)) {
						result[0] = b - a;
						result[1] = j;
						result[2] = i;
					} else if (result[0] > 1 && b - a == result[0]) {
						if (turn == 'o') {
							if (i < result[2]
									|| (i == result[2] && j < result[1])) {
								result[1] = j;
								result[2] = i;
							}
						}
						if (turn == 'x') {
							if (i > result[2]
									|| (i == result[2] && j > result[1])) {
								result[1] = j;
								result[2] = i;
							}
						}
					}
					for (int k = 0; k < 8; k++)
						for (int l = 0; l < 8; l++)
							tfield[k][l] = field[k][l];
				}
			if (result[0] > 1) {
				move(field, turn, result[2], result[1]);
				if (turn == 'o')
					opassed = false;
				if (turn == 'x')
					xpassed = false;
			} else {
				if (turn == 'o')
					opassed = true;
				if (turn == 'x')
					xpassed = true;
			}
			if (turn == 'o')
				turn = 'x';
			else
				turn = 'o';
		} while (!(opassed && xpassed));
		printfield(field);
		sc.close();
	}

	static void printfield(char[][] field) {
		for (int i = 0; i < 8; i++) {
			for (int j = 0; j < 8; j++)
				System.out.print(field[i][j]);
			System.out.println();
		}
	}

	static int count(char[][] field, char turn) {
		int result = 0;
		for (int i = 0; i < 8; i++)
			for (int j = 0; j < 8; j++)
				if (field[i][j] == turn)
					result++;
		return result;
	}

	static void move(char[][] field, char turn, int x, int y) {
		int[] dx = { 0, 1, 1, 1, 0, -1, -1, -1 };
		int[] dy = { 1, 1, 0, -1, -1, -1, 0, 1 };
		field[x][y] = turn;
		for (int i = 0; i < dx.length; i++) {
			if (x + dx[i] >= 0 && x + dx[i] < 8 && y + dy[i] >= 0
					&& y + dy[i] < 8) {
				if ((turn == 'o' && field[x + dx[i]][y + dy[i]] == 'x')
						|| (turn == 'x' && field[x + dx[i]][y + dy[i]] == 'o')) {
					for (int j = 2; j < 8; j++) {
						if (x + j * dx[i] >= 0 && x + j * dx[i] < 8
								&& y + j * dy[i] >= 0 && y + j * dy[i] < 8) {
							if (field[x + j * dx[i]][y + j * dy[i]] == '.')
								break;
							if (field[x][y] == field[x + j * dx[i]][y + j
									* dy[i]]) {
								for (int k = 1; k < j; k++)
									field[x + k * dx[i]][y + k * dy[i]] = field[x][y];
								break;
							}
						}
					}
				}
			}
		}
	}
}