一名苦逼的OIer,想成为ACMer

Iowa_Battleship

洛谷1247 取火柴游戏

原题链接

\(NIM\)游戏模板题。
设有\(n\)堆石子,第\(i\)堆有\(a_i\)个石子。
有结论:\(NIM\)游戏先手必胜仅当\(a_1 \oplus a_2 \oplus \dots \oplus a_{n - 1} \oplus a_n \neq 0\)\(\oplus\)表示按位异或)。
证明网上都有,这里就不写了。
至于第一步如何走,显然我们就是要让后手得到的局面是必败局面,所以我们要找到某一堆石子,取走\(a_i \oplus s\)枚石头即可(\(s\)为这些石堆全部异或起来的值)。

#include<cstdio>
using namespace std;
const int N = 5e5 + 10;
int a[N];
inline int re()
{
	int x = 0;
	char c = getchar();
	bool p = 0;
	for (; c < '0' || c > '9'; c = getchar())
		p |= c == '-';
	for (; c >= '0' && c <= '9'; c = getchar())
		x = x * 10 + c - '0';
	return p ? -x : x;
}
int main()
{
	int i, n, s = 0;
	n = re();
	for (i = 1; i <= n; i++)
	{
		a[i] = re();
		s ^= a[i];
	}
	if (!s)
	{
		printf("lose");
		return 0;
	}
	for (i = 1; i <= n; i++)
		if ((s ^ a[i]) < a[i])
		{
			printf("%d %d\n", a[i] - (s ^ a[i]), i);
			a[i] ^= s;
			break;
		}
	for (i = 1; i <= n; i++)
		printf("%d ", a[i]);
	return 0;
}

posted on 2018-10-26 15:51  Iowa_Battleship  阅读(168)  评论(0编辑  收藏  举报

导航