kmjp's blog

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

AtCoder ARC #151 : F - RGB Card Game

コードは短いんだけどね。
https://atcoder.jp/contests/arc151/tasks/arc151_f

問題

2人対戦のゲームを行う。
両者とも赤・青・黄色のカードを持っており、初期枚数が与えられる。

両者どちらかが先に攻めとなる。
攻めの方は手持ちのカードを1枚場に出す。
守りの方は、手持ちのカードのうち場のカードと同じ色のものを1枚場に出すか、何もしないことを選べる。
カードを出した場合、攻めと守りが交代される。

両者最適手を取るとき、勝者はどちらか。

解法

両者が1枚以上カードを持っている色で、自分の方が枚数が少ない場合、それは有利な色と呼ぶ。
両者が有利な色の数と、有利な色のカード枚数の総和を考えると、6値の場合分けで勝者が確定する。

int T;
ll C[2][3];

bool hoge() {
	int i,j,k,l,r,x,y; string s;
	ll NA=0,NB=0,NC=0,SA=0,SB=0,SC=0;
	FOR(i,2) FOR(j,3) cin>>C[i][j];
	FOR(j,3) if(C[0][j]&&C[1][j]) {
		if(C[0][j]<C[1][j]) NA++,SA+=min(C[0][j],C[1][j]);
		if(C[0][j]>C[1][j]) NB++,SB+=min(C[0][j],C[1][j]);
		if(C[0][j]==C[1][j]) NC++,SC+=min(C[0][j],C[1][j]);
	}
	if(NC==0) {
		return SA>=SB;
	}
	else if(NC==1) {
		if(NA==2) return 1;
		if(NB==2) return 0;
		if(SA-SB>=SC) return 1;
		if(SA-SB<=-SC) return 0;
		return (SA+SB+SC)%2;
	}
	else if(NC==2) {
		if(NA) return 1;
		if(NB) return 0;
		return SC%2;
	}
	else if(NC==3) {
		return SC%2==0;
	}
}

void solve() {
	
	
	cin>>T;
	while(T--) {
		if(hoge()) {
			cout<<"Takahashi"<<endl;
		}
		else {
			cout<<"Aoki"<<endl;
		}
		
	}
}

まとめ

解答見てしまうと結果はシンプルだけど、考察でこれ詰め切れる気がしないなぁ。