zoukankan      html  css  js  c++  java
  • Being a Good Boy in Spring Festival HDU

    桌子上有M堆扑克牌;每堆牌的数量分别为Ni(i=1…M);两人轮流进行;每走一步可以任意选择一堆并取走其中的任意张牌;桌子上的扑克全部取光,则游戏结束;最后一次取牌的人为胜者。 
    现在我们不想研究到底先手为胜还是为负,我只想问大家: 
    ——“先手的人如果想赢,第一步有几种选择呢?” 

    Input输入数据包含多个测试用例,每个测试用例占2行,首先一行包含一个整数M(1<M<=100),表示扑克牌的堆数,紧接着一行包含M个整数Ni(1<=Ni<=1000000,i=1…M),分别表示M堆扑克的数量。M为0则表示输入数据的结束。 
    Output如果先手的人能赢,请输出他第一步可行的方案数,否则请输出0,每个实例的输出占一行。 
    Sample Input

    3
    5 7 9
    0

    Sample Output

    1

    由于一次只能对一堆牌进行操作,假设我 操作第i堆牌(a张),抽出x张。

    那么其余n-1堆牌的异或值是固定为b.

    那么 (a - x)^ b == 0 时,对手必败。

    到此可能有人觉得必须历遍所有a求出那个值x满足条件。其实不必要

    由上式可知x只有唯一取值

     而且 一个数 与 b 异或等于 0 即表明 这个数等于b.

    所以反过来我们可以求出b, 令 a - x = b ;

    只要b满足 b < a; 即能构造出x使得 (a - x)^ b == 0 时,对手必败!

    而且经过举例,我发现总的异或值bns异或a后的结果正好是b的值

    AC Code:

    #include <cstdio>  
    #include <cstring>  
    #include <iostream>  
    #include <algorithm>  
    using namespace std;  
    int vis[102];
    int main(){
        int n;
        while(cin>>n&&n){
            int cnt=0,bns=0;
            for(int i=0;i<n;i++){
                cin>>vis[i];
                bns^=vis[i];
            }
            for(int i=0;i<n;i++){
                int ans=bns;
                ans^=vis[i];
                if(ans<vis[i]) cnt++;
            }
            cout<<cnt<<endl;
        }
  • 相关阅读:
    Java测试用例简介
    Hive使用入门
    Java中的GetOpt操作
    Tomcat的文件列表服务
    Hadoop MapReduce 初步学习总结
    hadoop集群调优-OS和文件系统部分
    02怎么学数据结构?
    01为什么学习数据结构?
    MySQL实战06の锁
    MySQL实战05の索引(下)
  • 原文地址:https://www.cnblogs.com/astonc/p/9991280.html
Copyright © 2011-2022 走看看