hdu1850

先判断是否是必胜,即将所有的状态进行异或 如果不等于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;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值