先判断是否是必胜,即将所有的状态进行异或 如果不等于0 就是先手必输 反之先手必胜;
这道题的数据都是先手必胜,只计算先手从必胜态操作到必输态,
如果(a1,a2, a3, a4 .......) 这些取异或 a1^a2^a3^a4....=k(k!=0)
则先手必胜,先手必可以通过改变某堆 的数量 使ai 为ai‘ 则
a1 ^a2^a3^a4^...^ai' = 0;
如何求取某一堆取多少时 再异或为0?
假如 要从 a1 中取走的 h 个剩 a1‘ 个,使 a1' ^a2^a3^...... = 0;
a1' = a1^k = a2^a3^a4^a5^......;(因为a^a = 0; 0^a =a;)
主要是看 某一堆取后 剩下的数 和 其他堆取异或 为0 是否存在;
即 ai^k < ai ;
例:5 7 9;
5^7^9 = (1011)2 = 11 = k;
5^k = 5^5^7^9 = 7^9 = 14 > 5; 没发取某个数使第一堆为 14;
7^k = 5^7^7^9 = 5^9 = 12 > 7; 同理没法;
9^k = 5^7^9^9 = 5^7 = 2 < 9;所以可以从第三堆中取走7个得2与 5^7 取异或 得0;即必输点;
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
int main()
{
int a[110];
int t;
while(cin >> t&&t)
{
int k = 0;
for(int i = 0; i < t; i++)
{
cin >> a[i];
k = k^a[i];
}
int cnt = 0;
for(int i = 0; i < t; i++)
if((k^a[i]) < a[i])
cnt++;
cout << cnt << endl;
}
return 0;
}
hdu1850
最新推荐文章于 2019-03-17 20:57:32 发布