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.io.*;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.lang.ArrayIndexOutOfBoundsException;
import java.math.BigInteger;

import javax.script.AbstractScriptEngine;


/**
 * @author yoshikyoto
 */
class Main extends MyUtil{
	// public static Graph g;
	public static void main(String[] args) throws Exception{
		// ボードの入力を受ける
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		char[][] table = new char[8][8];
		for(int i = 0; i < 8; i++){
			table[i] = br.readLine().toCharArray();
		}
		
		Board b = new Board(table);
		char[] marks = {'o', 'x'};
		int turn = 0;
		boolean prev_finish_flag = false;
		while(true){
			char m = marks[turn];
			boolean curr_finish_flag = false;
			if(b.turn(m) == 0) curr_finish_flag = true;
			if(prev_finish_flag && curr_finish_flag) break;
			
			turn = (turn + 1) % 2;
			prev_finish_flag = curr_finish_flag;
			// b.print();
			// System.out.println();
		}
		b.print();
	}
}

class Board{
	char[][] table;
	Board(char[][] table){
		this.table = table;
	}
	
	void print(){
		for(int i = 0; i < 8; i++){
			StringBuffer buf = new StringBuffer();
			for(int j = 0; j < 8; j++){
				buf.append(table[i][j]);
			}
			System.out.println(buf.toString());
		}
	}
	
	int turn(char m){
		int max_i = -1, max_j = -1;
		int max_cnt = 0;
		
		for(int i = 0; i < 8; i++){
			for(int j = 0; j < 8; j++){
				if(table[i][j] != '.') continue;
				int cnt = check(m, i, j, false);
				if(cnt > max_cnt && m == 'o' ||
						cnt >= max_cnt && m == 'x'){
					max_cnt = cnt;
					max_i = i;
					max_j = j;
				}
			}
		}

		// System.out.println("" + m + " " + max_cnt + " " + max_i + " " + max_j);
		if(max_cnt > 0){
			check(m, max_i, max_j, true);
		}
		return max_cnt;
	}
	
	static int[] di = {-1,-1,-1,0,0,1,1,1};
	static int[] dj = {-1,0,1,-1,1,-1,0,1};
	int check(char m, int i, int j, boolean replace_flag){
		int sum = 0;
		for(int k = 0; k < 8; k++){
			int cnt;
			for(cnt = 1; cnt <= 8; cnt++){
				try{
					char table_mark = table[i + cnt*di[k]][j + cnt*dj[k]];
					if(table_mark == m){
						// 必要ならここで置き換える
						if(replace_flag){
							table[i][j] = m;
							for(int mult = cnt-1; mult > 0; mult--){
								try{
									table[i + mult*di[k]][j + mult*dj[k]] = m;
								}catch(Exception e){
									continue;
								}
							}
						}
						break;
					}else if(table_mark == '.'){
						cnt = 1;
						break;
					}
				}catch(Exception e){
					// マスを飛び出した場合
					// System.err.println(e);
					cnt = 1;
					break;
				}
			}
			sum += (cnt - 1);
		}
		return sum;
	}
}



// --- ここから下はライブラリ ----------
/**
 * MyUtil
 * @author yoshikyoto
 */
class MyUtil {
	public static int[] cp(int[] a){
		int[] b = new int[a.length];
		for(int i = 0; i < a.length; i++) b[i] = a[i];
		return b;
	}
	public static int toInt(boolean[] a){
		int pow = 1, ret = 0, l = a.length;
		for(int i = 0; i < l; i++){
			if(a[i]) ret += pow;
			pow *= 2;
		}
		return ret;
	}
	static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	public static int ins[];
	public static int[] readIntMap() throws IOException{return parseInt(readLine().split(" "));}
	public static int readIntMap(int i) throws Exception{
		if(i == 0) ins = readIntMap();
		return ins[i];
	}
	public static int[][] readIntMap(int n, int m) throws IOException{
		int[][] ret = new int[n][];
		for(int i = 0; i < n; i++) ret[i] = readIntMap();
		return ret;
	}
	public static int[] readIntToMap(int n) throws IOException{
		int[] ret = new int[n];
		for(int i = 0; i < n; i++) ret[i] = readInt();
		return ret;
	}
	public static int[] readNoDistIntMap() throws IOException{
		String[] strs = readLine().split("");
		int l = strs.length;
		int[] ret = new int[l-1];
		for(int i = 1; i < l; i++)
			ret[i-1] = parseInt(strs[i]);
		return ret;
	}
	public static String readLine() throws IOException{return br.readLine();}
	public static int readInt() throws IOException{return Integer.parseInt(br.readLine());}
	public static int[] parseInt(String[] arr){
		int[] res = new int[arr.length];
		for(int i = 0; i < arr.length; i++)res[i] = Integer.parseInt(arr[i]);
		return res;
	}
	public static double[] parseDouble(String[] arr){
		double[] res = new double[arr.length];
		for(int i = 0; i < arr.length; i++)res[i] = Double.parseDouble(arr[i]);
		return res;
	}
	public static boolean[] parseBool(String[] arr){
		int[] t = parseInt(arr);
		boolean[] res = new boolean[t.length];
		for(int i = 0; i < t.length; i++){
			if(t[i] == 1){res[i] = true;
			}else{res[i] = false;}
		}
		return res;
	}
	public static int parseInt(Object o){
		return Integer.parseInt(o.toString());
	}
}