洛谷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) 编辑 收藏 举报