zoukankan      html  css  js  c++  java
  • 经典博弈

    pku2234 Matches game!!!!!
    hdu1846 brave game. if(n%(m+1)==0)n是必败点 !!!!!!
    pku2484 A Funny Game. if(n>=3)n是必败点 !!!!!!
    hdu1851 A Simple Game!!!!!!
    for(i=1,s=0;i<=n;i++){scanf("%d%d",&m,&l);s^=m%(l+1);}
    hdu1847 GoodLuck in CET-4 Everybody.if(n%3==0)n是必败点
    hdu1730 Northcott Game
    hdu1517 A Multiplication Game,ecjtu1038
    hdu1525 Euclid's Game pku2348,ecjtu1039
    hdu2147 kiki's game
    hdu1907 John 取尽者败 pku3480
    if(a1=a2=...=an=1) n为奇数必败,否则s=a1^a2...^an 
    hdu2509 Be the Winner 取尽者败.zju1616 ,ecjtu1108
    pku2068 nim-2n个人的game.ecjtu1112. 
    pku1740 A New Stone Game.
    pku1704 Georgia and Bob
    pku2975 Nim-有多少种win的策略
    hdu2176 取(m堆)石子游戏-有多少种win的策略
    pku2368 Buttons
    ecjtu1006 Stone Game 放(1堆)石子游戏
    hdu1729 Stone Game 放(n堆)石子游戏
    hdu2516 取(2倍)石子游戏 
    hdu2580 a simple stone game(取k倍)
    pku1082 Calendar Game
    hdu1848 Fibonacci again and again 。ecjtu1113 
    hdu1536(hdu1944,pku2960,ecju1110) S-Nim 
    ecjtu1116 Fibonacci again
    nuaa1516,ecjtu1117 质数取石子
    pku2348,ecjtu1039 Euclid's Game
    
    
    pku2234 Matches game
    
    
    取石子游戏
    两个人面队若干堆石子(或硬币,火柴,棋子)进行游戏。各堆含有
    a1,a2,…,ak枚硬币。
    游戏规则如下:
    1. 两人轮流取子,当轮到你取子时,你不能不取
    2. 取子者只能从某堆中取子,取走一堆中的任意个子
    3. 最后取子者为游戏的得胜者,或当轮到你取子时,你没有子可取
        你为败者。 
    :
    结论1. 如果只有一堆,即k=1,则第一取子者胜;
    结论2. 如果只有2堆,a1,a2, a1=a2则第2取子者胜;
        第1取子者在某堆取走c个,则 第2取子者在另1堆也取走c个,
        2堆仍然相等。
        即 第1取子者取后2堆不相等, 第2取子者取后2堆相等,最后 
        取子者是 第2取子者.
    结论3. 如果只有2堆,a1,a2, a1<>a2则第1取子者胜;    
        第1取子者在多的1堆取 abs(a1-a2)个,取后2堆相等。 
    定义: 如果有k堆,堆数用无序向量(a1,a2,...,ak)表示,如果第1
    取子者不能获胜,则称 (a1,a2,...,ak)为必败点.
    例 . k=2时,(a,a) 为必败点
    结论4: 无序向量(a1,a2,...,ak),如果经过1次取子后变为必败点
    则(a1,a2,...,ak)为必胜点, 无论如何取都不能变为必败点,则为
    必败点 。 
    例 . k=2时,(20,25) 为必胜点 ,1次取子后变为必败点(20,20)
         k=3 ,(20,20,25) 为必胜点 ,1次取子后变为必败点(20,20)
         k=2,(20,20),无论如何取都变不了必败点,(20,20) 是必败点。
         
        k=2时,相同(相等)必败,不等必胜。
        看看C语言的异或运算^
    性质1.若a=b,则a^b=0;
    性质2.若a<>b,则a^b<>0; 
    性质3.若a^b=c,则a^c=b;
          a^a^b=a^c ==> b=a^c;
    性质4.令s=a1^a2^...^an,si是a1,a2,...,an中除 ai以外的其余n-1个
          的异或值, 则
           si=s^ai 
    性质5.令s=a1^a2^...^an.     
          若 s=0,则
          si=ai ,(i=1,2,...,n )
          当ai发生变化后,s<>0;
    性质6.令A=(a1,a2,...,an),B=(b1,b2,...,bm,C=(a1,a2,...,an,b1,b2,...,bm).
         记为C=A+B.
         若A,B是必败点,则C是必败点 
         若A,B中有一个是必败点,另1个是必胜点,则C是必胜点.
    两个必胜点之和不必是必胜点.    
           
    定义:若A+B是必败点,则称A与B等价
    
    若A==B, 则A与B等价
    
    性质7. A+A 是必败点。
    
           
        3^5 =? 在C程序中 用printf("%d\n",3^5); 就知道了
         异或运算^是:相同为0,不同为1 ,不进位
         3,5的2进制数是   011,101
                         0 1 1
                         1 0 1
            ------------------------
                         1 1 0
        因此 3^5=6 =(110)2进制
    利用或运算^,结论2,结论3为
    结论2‘k=2,如果a1^a2=0, 则第2人胜                                     
    结论3‘k=2,如果a1^a2<>0, 则第1人胜
    
    k>2 如何 ?                                 
    k=3. (a1,a2,a3) =(3,6,9) 
    3^6=5, 3^6^9=5^9<>0
    对 (3,6,9)取子变为 (3,6,5) ,3^6^5=5^5=0
    对 (3,6,5)无论如何取子都不能使其异或为0
    一般地 有
    定理 令s=a1^a2^...^ak,si=s^ai,
       
         (1)若s<>0,则存在 i,将 ai缩小为si后 s=0;
         (2)若s=0,则 将任何数ai做任何缩小后 s<>0;    
    
    
    #include <stdio.h>
    int main()
    {
        int m,n,s;//n<=1000000 
        while(scanf("%d",&m)!=EOF)
        {
            s=0;
            while(m--)
            {
                scanf("%d",&n);
                s=s^n;
            }
            if(s==0)printf("No\n");
            else printf("Yes\n");
        }
    return 0;
    }有m堆石子,各堆有n颗石子。
    
    hdu1851A Simple Game
    方法:
       这里采用的对每个事件中的每组数据 ,先用第一个数对比第二个数大1的数求余,再对各余数异或;
       如果得到各个余数的异或值为零则有 Agrael胜得,对应的输出"Yes",反之输出“No”;
       假设每次输入的数据为m,l;则有s=m1%(l1+1)^m2%(l2+1)^m3%(l3+1)^…………^mn%(ln+1); 
       当s=0时,输出Yes;
       当s!=0 时输出No; 
       例 m1=100 ,l1=16 
          m2=98,   l2=8    
         有 m1%(l1+1)=15;m2%(l2+1)=8;
         得 15^8!=0; 所以这里会输出 “No ”;
         怎么样理解呢?
        因为只有当异或等于0时,这里是必胜点 ;当在这一点时,对方怎么拿都不能达到必胜点;当对方拿多少时
        自己在另一处也拿多少,可以维持着处于必胜的局面;
        但是在以上这一点时,当对方 在一堆中拿中 7个后,就变成好对方的必胜点;自己就必败了;
    
    #include<stdio.h>
    int main()
    {
    int T,n,m,s,l;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n); 
         s=0;
        while(n--)
        { 
          scanf("%d%d",&m,&l);
          s^=m%(l+1);
        }
    
           
       if(s==0)printf("Yes\n");
       else printf("No\n");                 
    } 
    return 0; 
    }
    
         
         
    hdu1525 Euclid's Game pku2348 
        fun(int a ,int b)//a>=b
        { if( a%b==0)return 1;
          k=a/b;r=a%b;//a=k*b+r   25 7   ,7 4, 11 7
          if(k>1)return 1;      
          return 1-fun(b,r);
        } 
    pku1740 A New Stone Game
    a1,a2,a3…………an为必败点<=>当n为偶数时,对a1--an进行从小到大或
    从大到小排序,如果有a1=a2,a3=a4,…………an-1=an,
    当n为奇数时以及其它的情况则必胜。
    pku1704 Georgia and Bob. 将p[]排序.
    s=(p[n]-p[n-1])^(p[n-2]-p[n-3])^....^(p[2]-p[1])
       if(n%2==1 )    将 ^(p[2]-p[1])改为 ^(p[1]-p[0]),p[0]=0;
    
    pku2975 Nim-有多少种win的策略
    
    解题报告:
    取石子问题
    此题求第一次取时能够得到必胜的取法;
    首先我们按照公式对所有的石子的异或值S=a1^a2^a3.....^an;
    若异S==0则说明是必败点。
    输出 0;
    若S不等于0;
    则对第i堆石子 我们求出除去第i堆石子其余石子的异或值(以 7 11 13为例)
    其中 对第1堆 我们求出11^13=6 则只要把第1堆中拿去1个 变成 6个 既OK
    同理 对第2堆 我们求7^13=10 则只要把第2堆中拿去1个 变成 10个 既OK
    ....
    那么总结出
    设 Si=a1^a2^a3....ai-1^ai+1^ai+2....an;    (除去第i堆石子其余石子的异或值)
    若Si<ai 则说明我们可以找到一种取胜方法
    for(i=1,num=0;i<=m;i++)
    { k=s^a[i];//s=a[1]^a[2]^...^a[n]
       if(k<a[i])num++;
    }
    ecjtu1006 Stone Game 放(1堆)石子游戏
    f[d]=d*(d+1): 2,6,12,20,30,42,56
    if(s<=f[d]&&s>f[d-1])s的必败点是 d-1;
    s=1000,1000 的必败点是31,31的必败点是5,5的必败点是 1
    hdu1729 Stone Game 放(n堆)石子游戏
    s1,c1;s2,c2;...sn,cn;
    bi是>=ci的最小必败点,ai=bi-ci; s=a1^a2^...^an
    
    hdu2516 取(2倍)石子游戏 
    1,2,3,5,8,13都是必败点,斐波那契数列中的数都是必败点。
    hdu2580 a simple stone game(取k倍)
    a[i]=i,i<=k+1是必败点,
    必败点a[i+1]=a[i]+a[p],k*a[p]>=a[i],k*a[p-1]<a[i]; 
    pku1082 Calendar Game
    hdu1848 Fibonacci again and again .ecjtu1113 。3堆 
    int F(int k)
    { int g[15],i;//计算k的等价类数E[k],
    /*
    k个石子,取子后变为 b[j]=k-a[j]个 
    b[1],b[2],...,b[s] ,和b[j]等价的最小数是 E[b[j]]
    E[b[1]],E[b[2]],...,E[b[s]] 
    E[k]=   E[b[j]]中没有出现的最小数 . 
    必败点等价于0;
    k=fib[1],E[k]=1;
    */
    for(i=0;i<15;i++)g[i]=0;
    for(i=1;a[i]<=k;i++)g[E[k-a[i]]]=1; 
    for(i=0;i<=k;i++)if(g[i]==0)return i; 
    }
    
    hdu1536(hdu1944,pku2960,ecju1110) S-Nim 
    freopen("data1.in","r",stdin); S{2,3}
       
    ecjtu1116 Fibonacci again
    F[i]=0,i是必败点; F[i]=1,i是必胜点;
    i是 Fibonacci数,F[i]=1;
    if(F[i]==0)
    { for(j=1;fib[j]<=i;j++)if(F[i-fib[j]]==0){F[i]=1;break;}}
    nuaa1516,ecjtu1117 质数取石子
    原文地址<http://code.google.com/p/zldry88-acm/issues/detail?id=7>
  • 相关阅读:
    ubuntu video and audio
    js type
    jumpserver 堡垒机环境搭建
    ubuntu dnsmasq
    bind--dns-docker---[nslookup/dig]
    java maven scope compile,provide,system,test,runtime
    docker install and minikube install
    nginx break-circus orange api-gateway
    一个IP能建立的最大连接数是多少?
    Docker 在6.4上安装
  • 原文地址:https://www.cnblogs.com/qianmacao/p/2458632.html
Copyright © 2011-2022 走看看