P6585 中子衰变

我们偶数的时候只要对称操作。
奇数的话,我们定义(1)的相反数为(-1),(0)相反数为(0)
我们维护最长的两边的相反串,中间一段除了一个端点,其他均被染成同色。
那么如果对方染端点,那么我们两个端点相邻必有一个可染上相同颜色,此时相反串长度减1.
如果对方染和端点相邻,那么我们直接染端点。此时相反串长度减1。
否则我们在对称点上染上相反颜色。

#include<iostream>
#include<cstdio>
#define ll long long 
#define N ((1 << 10) + 10)

ll num[N];

ll n,id;

int main(){
	scanf("%lld%lld",&n,&id);
	if(n & 1){
		std::cout<<1<<std::endl;//选择后手 
		ll l = (n / 2),r = (n / 2),z = 0;//维护中间段
		ll x,y;
		ll m = (n - 1) / 2;
		while(scanf("%lld%lld",&x,&y) == 2){
			ll r = (n - m),l = m + 1;
			num[x] = y;
			if(x == l || x == r){
				z = y;
				if(!num[l - 1] && (num[l - 2] == 0 || num[l - 2] == y))
				std::cout<<l - 1<<" "<<y<<std::endl,num[l - 1] = y,m --;
				else
				std::cout<<r + 1<<" "<<y<<std::endl,num[r + 1] = y,m --;				
			}else
			if(((x == l + 1 && !num[l]) || (x == r + 1 && !num[r])) && y == z){
				if(x == l + 1)
				std::cout<<l<<" "<<y<<std::endl,num[l] = y;
				if(x == r + 1)
				std::cout<<r<<" "<<y<<std::endl,num[r] = y;
				m -- ;
			}
			else
			std::cout<<(n - x + 1)<<" "<<((y == 1) ? -1 : 1)<<std::endl,num[n - x + 1] = (y == 1) ? -1 : 1;
			fflush(stdout);
		} 
	}else{
		ll x,y;
		std::cout<<1<<std::endl;//选择后手。
	 	while(scanf("%lld%lld",&x,&y) == 2){
	 		std::cout<<(n - x + 1)<<" "<<y<<std::endl;
			fflush(stdout);
		}
	}
}
原文地址:https://www.cnblogs.com/dixiao/p/15178936.html