码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 1850 题解

时间:2019-11-03 21:48:02      阅读:68      评论:0      收藏:0      [点我收藏+]

标签:href   扑克牌   问题   turn   第一步   答案   can   amp   cpp   

题目

题意:n堆扑克牌,每次可以取走一堆中任意张数的扑克牌,问先手胜利第一步有几种可能。

这一题如果除去后面一问就直接问先手赢还是后手赢,这就是一道简单的 $ NIM $ 博弈问题。

定理

$ ????????? NIM $ 博弈先手必胜,当且仅当 $ A_1 xor A_2 xor A_3....xorA_ixor.....A_n \neq 0 $

具体证明李煜东书上有,这里不做阐述。(可用数学归纳法进行证明

在了解到这个定理后我们还要知道一个式子

$ a ?xor ?b =c ?,b ?xor ? c =a ?,a ?xor ?c =b ?, $

首先如果当前场面先手必败,那么答案就是 $ 0 $

如果当前场面先手必胜那么 $ A_1 xor A_2 xor A_3....xorA_ixor.....A_n \neq 0 $ ,我们可以假设存在一个 $ A_j $ 使得 $ A_1 xor A_2 xor A_3....xorA_jxor.....A_n = 0 $ 那么我们可以设 $tmp= A_1 xor A_2 xor A_3....xorA_ixor.....A_n \neq 0 $ 就可以得到 $ tmp ?xor A_i= 0 ?xor A_j $ 即 $ tmp ?xor A_i= A_j $ 那么很显然我们就是要去统计有多少个合法的 $ A_j $那么依据题意我们知道保证 $ A_i > A_j $ 即可。

代码

#include<bits/stdc++.h>
using namespace std;
int n,a[110];
int main(){
    while(scanf("%d",&n)&&n){
        int tmp=0,ans=0;
        for(int i=1;i<=n;++i){
            scanf("%d",&a[i]);
            tmp^=a[i];
        }
        for(int i=1;i<=n;++i){
            if(a[i]>(tmp^a[i])) ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}

hdu 1850 题解

标签:href   扑克牌   问题   turn   第一步   答案   can   amp   cpp   

原文地址:https://www.cnblogs.com/donkey2603089141/p/11789216.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!