kmjp's blog

競技プログラミング参加記です

Golden Week Contest 2015 : C - Snukeと対戦!

なかなか面白いリアクティブ。
http://gwcontest2015.contest.atcoder.jp/tasks/gw2015_c

問題

H*Wのグリッドと白黒の碁石を使ったゲームを行う。
このゲームは2人で行うもので、交互に石を空きセルに置く。
置く石の色は白黒どちらでもよいが、隣接マスに同じ色の石がある場合、その場所にその色の石を置くことはできない。
自分の手番で石を置けない場合負けとなる。

プレイヤーは先手後手を選べる。
自動応答の相手に対し勝利せよ。

解法

基本アプローチは「先に相手に打たせて、自分は中心に点対称に打てば、先に相手が苦しくなる」である。

  • 高さ・幅ともに奇数の場合
    • プレイヤーは初手を中央に打つ。
    • 以後、相手の手に対し同じ色の石を点対称の位置に打つ。
  • 高さ・幅少なくともどちらか偶数の場合
    • プレイヤーは後手を取る。
    • 以後、相手の手に対し逆の色の石を点対称の位置に打つ。
int H,W;

void solve() {
	int i,j,k,l,r,x,y; string s;
	
	scanf("%d%d",&H,&W);
	if(H*W%2==1) {
		_P("First\n");
		fflush(stdout);
		_P("%d %d %d\n",H/2+1,W/2+1,1);
		fflush(stdout);
		while(1) {
			scanf("%d%d%d",&y,&x,&r);
			if(r==-1) break;
			_P("%d %d %d\n",H+1-y,W+1-x,r);
			fflush(stdout);
		}
	}
	else {
		_P("Second\n");
		fflush(stdout);
		while(1) {
			scanf("%d%d%d",&y,&x,&r);
			if(r==-1) break;
			_P("%d %d %d\n",H+1-y,W+1-x,r^1);
			fflush(stdout);
		}
	}
	
}

まとめ

最初に思い浮かんだのがヒカルの碁の初手天元でした。
おかげですんなり解けた。