zoukankan      html  css  js  c++  java
  • HDU 2176 取(m堆)石子游戏 && HDU1850 Being a Good Boy in Spring Festivaly

    HDU2176题意:

    m堆石子,两人轮流取.只能在1堆中取.取完者胜.先取者负输出No.先取者胜输出Yes,然后输出怎样取子.

    通过 SG定理 我们可以知道每一个数的SG值,等于这个数到达不了的前面数中的最小值。本题题意和尼姆博弈一样,即可以在一堆中任意个石子,所以也就是说每个数都可以到达前面经过的每一个数,所以每一个数的SG值就是它本身。又因为有好多堆石子,所以可以看作多个一堆石子的游戏,我们可以让n代表每一堆石子的数量,那么让所有堆的SG(n)相互异或得到的结果就是答案(这里只是用SG定义来证明了一下尼姆博弈的作法)

    HDU2176题解:

    如果给出的每一堆石子的总数n相互异或得到0,就证明这是一个必败态

    那么做这一道题先判断一个全部异或后得到的是不是0,如果是0直接输出No

    不是0的话,就要找方法使得一步操作过后局面变成必败态,变成必败态要是他们所以异或起来是0,而一个数和它自己异或就是0

    所以我们可以从所有石子堆中找出来一个数,让它变成除自己外剩下所有值的异或值,这样全部异或起来就是0了

    比如(用^代表异或):

    (1 2 5)  1^2=3 ,那么我们可以从5中拿走2个石子,这样就变成了必败态

    (1 6 9)  1^6=7,那么可以从9中拿走2个石子,这样也变成了必败态

    代码:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<math.h>
     6 #include<stack>
     7 #include<math.h>
     8 using namespace std;
     9 typedef long long ll;
    10 const int maxn=1000005;
    11 int v[maxn];
    12 int main()
    13 {
    14     int n;
    15     while(~scanf("%d",&n))
    16     {
    17         if(!n) break;
    18         int flag=0;
    19         for(int i=0;i<n;++i)
    20         {
    21             scanf("%d",&v[i]);
    22             flag^=v[i];
    23         }
    24         if(!flag)
    25         {
    26             printf("No
    ");
    27             continue;
    28         }
    29         printf("Yes
    ");
    30         for(int i=0;i<n;++i)
    31         {
    32             if(v[i]>(flag^v[i]))
    33             {
    34                 printf("%d %d
    ",v[i],flag^v[i]);
    35             }
    36         }
    37     }
    38     return 0;
    39 }
    View Code

    HDU1850题意:

    和上一题和基本上一样,就是问你如果能赢,第一步拿石子有多少种方法

    题解:

    上一道题就是在判断从那一堆中拿石子,所以这一道题只需要稍微改变一下就可以了

    代码:

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<iostream>
     4 #include<algorithm>
     5 #include<math.h>
     6 #include<stack>
     7 #include<math.h>
     8 using namespace std;
     9 typedef long long ll;
    10 const int maxn=1000005;
    11 int v[maxn];
    12 int main()
    13 {
    14     int n;
    15     while(~scanf("%d",&n))
    16     {
    17         if(!n) break;
    18         int flag=0;
    19         for(int i=0;i<n;++i)
    20         {
    21             scanf("%d",&v[i]);
    22             flag^=v[i];
    23         }
    24         int ans=0;
    25         for(int i=0;i<n;++i)
    26         {
    27             if(v[i]>(flag^v[i]))  ans++;
    28         }
    29         printf("%d
    ",ans);
    30     }
    31     return 0;
    32 }
    View Code
  • 相关阅读:
    RabbitMQ笔记-基础知识
    什么是HashMap【转】
    Mysql笔记-查询缓存
    Redis笔记-配置文件
    Autofac-.net core控制台使用依赖注入【转】
    布隆过滤器(c#简单实现)【转】
    Redis笔记-布隆过滤器组件
    StackExchange.Redis笔记-分布式锁
    StackExchange.Redis笔记-发布订阅
    StackExchange.Redis笔记-性能调优【转】
  • 原文地址:https://www.cnblogs.com/kongbursi-2292702937/p/11344917.html
Copyright © 2011-2022 走看看