メモ

yukicoderでゆるふわgolf

yukicoder No.601 Midpoint Erase

問題はこちら
No.601 Midpoint Erase - yukicoder

(x1,y1)と(x2,y2)の中点が格子点
⇔「(x1+x2)/2が整数」かつ「(y1+y2)/2が整数」
⇔「x1とx2の偶奇が等しい」かつ「y1とy2の偶奇が等しい」

よって与えられた点たちを、「x座標が偶数/奇数、y座標が偶数/奇数」という4つのグループに分けると、中点が格子点になるよう2点を選ぶことは、同じグループから2点を選ぶことと同値。
各グループに属する点の個数を数えて、全部で何組作れるかを見ればよい

a[2][2],n,x,y;
main(){
	scanf("%d",&n);
	while(n--){
		scanf("%d%d",&x,&y);
		a[x%2][y%2]++;
	}
	if(a[0][0]/2+a[0][1]/2+a[1][0]/2+a[1][1]/2)%2==1)puts("Alice");
	else puts("Bob");
}

作ることが出来る組の数(つまりa[0][0]/2+a[0][1]/2+a[1][0]/2+a[1][1]/2)をsとする。
sを最後に計算するのではなく、読み込みながら計算することを考える。
sが増えるのはa[*][*]が奇数から偶数に変化したときなので、s+=a[*][*]++%2とすることが出来る。
さらによく考えると、sは偶奇のみが必要なので、実は%2を省略してs+=a[*][*]としてよい。
また、配列は明らかに1次元4要素にまとめられる

s,x,a[4];
main(y){
	for(gets(&y);~scanf("%d%d",&x,&y);)s+=a[x%2*2+y%2]++;
	puts(s%2?"Alice":"Bob");
}

95B
nの読み飛ばしを頑張るパターンも考えたが96Bにしかならず

s,x,y,a[4];
main(i){
	for(;~scanf("%d",&y);x=y)s^=i--&!!i&&a[x%2*2+y%2]++%2;
	puts(s?"Alice":"Bob");
}