kmjp's blog

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

yukicoder : No.2631 Rectangle Grid Game

方針を思いついても、短く書くの難しいな。
https://yukicoder.me/problems/no/2631

問題

H*Wのグリッドが与えられ、2人でゲームを行う。
初期状態でそれぞれ1つのマスの駒を行う。
以後、各人のターンでは以下の動作を行う。

  • 駒を移動する。ただし、自分が占拠済みの矩形と、移動先のマスを包含する最小の矩形が、相手が占拠済みの矩形と重なってはならない。
  • 駒を移動後、自分が占拠済みの矩形と、移動先のマスを包含する最小の矩形を占拠した状態となる。

最終的により多くの領域を占拠した方が勝利となる。
2つの駒の初期配置のうち、先手が必勝となるのは何通りか。

解法

先手の駒を矩形の左上1/4に配置したとき、先手が負ける後手の駒の配置を考える。
これはだいたい先手の駒と、グリッドの中心を含む矩形領域である(厳密には右や下に1はみ出すこともある)
よってこれらを数え上げればよい。

ll H,W;
const ll mo=998244353;

ll hoge(ll X,ll Y) {
	ll A=H/2+2;
	ll B=W/2+2;
	ll ret=0;
	ret+=(H*W-A*B)%mo*X%mo*Y%mo;
	ret+=B*(X*(X+1)/2%mo)%mo*Y%mo;
	ret+=A*(Y*(Y+1)/2%mo)%mo*X%mo;
	ret-=(X*(X+1)/2%mo)*(Y*(Y+1)/2%mo)%mo;
	return (ret%mo+mo)%mo;
	
};


void solve() {
	int i,j,k,l,r,x,y; string s;
	
	cin>>H>>W;
	ll ret=0;
	ret+=hoge(H/2,W/2);
	ret+=hoge((H+1)/2,W/2);
	ret+=hoge(H/2,(W+1)/2);
	ret+=hoge((H+1)/2,(W+1)/2);
	
	
	cout<<ret%mo<<endl;
}

まとめ

1数え間違えそうな箇所が多くて怖い。