博弈论初级入门题目

来源:互联网 发布:c4d mac破解版百度云 编辑:程序博客网 时间:2024/04/30 12:59

详细资料参见博弈论入门

hdu 1846 巴什博弈,只要n%(m + 1)==0肯定输。

#include <cstdio>int main(){    int T ;    int n ;    int m ;    //freopen("hdu1846.in" ,"r" , stdin) ;    scanf("%d" , &T) ;    for( ; T-- ; ){        scanf("%d%d" , &n , &m) ;        puts(n%(m+1) ? "first" : "second") ;    }    return 0;}
hdu 1847推一下就可以得到结果了。当然也可以用SG函数去求解。

#include<cstdio>int main(){    int n ;    while(scanf("%d" , &n)!=EOF){        puts(n%3 ? "Kiki" : "Cici") ;    }    return 0 ;}
hdu 1848 直接写SG函数,然后就是异或判断就行了。

#include <cstdio>#include <cstring>#define maxn 1010int sg[maxn] ;int fib[maxn] ;bool mex[maxn] ;int top ;void get_Fib(){    fib[0] = 1 ;    fib[1] = 1 ;    for(int i = 2 ; i < maxn ; i ++){        fib[i] = fib[i - 1] + fib[i - 2] ;        if(fib[i] >= 1000){            top = i ;            break   ;        }    }}void get_sg(){    sg[0] = 0 ;    for(int i = 1 ; i <= 1000 ; i ++){        memset(mex , 0 , sizeof(mex)) ;        for(int j = 1 ; j <= top ; j ++){            if(i < fib[j])                break ;            mex[ sg[i - fib[j]] ] = 1 ;        }        int j = 0 ;        while(mex[j++]) ;        sg[i] = --j ;    }}int main(){    int m , n , p ;    //freopen("hdu1848.in" ,"r" , stdin) ;    get_Fib() ;    get_sg()  ;    while(scanf("%d%d%d" , &n , &m , &p) , n||m||p){        puts((sg[n]^sg[m]^sg[p]) ? "Fibo" : "Nacci" ) ;    }    return 0 ;}
hdu 1849  Nim的变形。

#include <cstdio>int main(){    int m ;    while(scanf("%d" , &m) , m){        int ans = 0 ;        int p ;        for(int i = 0 ; i < m ; i ++){            scanf("%d" , &p) ;            ans = ans^p ;        }        puts(ans ? "Rabbit Win!" : "Grass Win!") ;    }    return 0 ;}

hdu 1850 Nim的变形,输出有多少中情况的。先将全部的数异或,然后将异或的结果与第i堆数量进行异或,如果得到的结果小于该堆的数量,则有一种方案。具体的推理很简单,仔细想一下就知道了。

#include <cstdio>#define maxn 100int num[maxn] ;int main(){    int n ;    int nimSum = 0 ;    freopen("hdu1850.in" , "r" , stdin) ;    while(scanf("%d" , &n) , n){        nimSum = 0 ;        for(int i = 1 ; i <= n ; i ++){            scanf("%d" , &num[i]) ;            nimSum ^= num[i] ;        }        int ans = 0 ;        for(int i = 1 ; i <= n ; i ++){            if((nimSum ^ num[i]) < num[i]){                ans ++ ;            }        }        printf("%d\n" , ans) ;    }    return 0 ;}

hdu 2149 又是一道巴什博弈,只不过这次要输出第一次可以出哪些值。直接上代码吧,

#include <cstdio>int main(){    int n , m ;    for( ; scanf("%d%d" , &m , &n)!=EOF ;){        if(m%(n+1) == 0){            puts("none") ;            continue ;        }        if(m/(n + 1)){            printf("%d\n" , m%(n + 1)) ;        }        else{            for( ; m <= n ; m ++){                printf("%d" , m) ;                if(m != n)                    printf(" ") ;            }            printf("\n") ;        }    }}

hdu 2188 巴什博弈

#include <cstdio>int main(){    int T ;    int n , m ;    scanf("%d" , &T) ;    while(T--){        scanf("%d%d" , &n , &m) ;        puts((n%(m + 1)) ? "Grass" :"Rabbit" ) ;    }    return 0 ;}

hdu 1079 直接用SG函数,或者推一下规律。

#include <cstdio>int main(){    int y , m , d ;    int T ;    scanf("%d" , &T) ;    while(scanf("%d%d%d" , &y , &m , &d) , T--){        if( (m + d)%2 == 0 || ( d == 30 && (m == 11 || m == 9) ) )            puts("YES") ;        else            puts("NO") ;    }    return 0 ;}
hdu 1517 找规律,或者SG函数

#include<stdio.h>int main(){    double  n;    while(scanf("%lf",&n)!=EOF)    {        while(n>18)n/=18;        if(n<=9) printf("Stan wins.\n");        else   printf("Ollie wins.\n");    }    return 0;}
hdu 1404 按照给定的过程模拟一下,计算出每个点的SG值

/** 模拟 + sg函数*/#include <cstdio>#include <cstring>#include <cstdlib>const int maxn = 1000000 ;char str[10] ;int  sg[maxn + 1] ;void init(){    memset(sg , 0 , sizeof(sg)) ;    int val ;    int len ;    char curr ;    char j    ;    char t[10];    int tmp  ;    for(int i = 1 ; i <= maxn ; i ++){        val = 1 ;        itoa(i , str , sizeof(str)) ;        len = strlen(str) ;        for(int k = 0 ; k < len && val ; k ++){            curr = str[k] ;            j = '0' ;            if( !k )                j ++ ;            if(curr == '0'){                for(j = 0 ; j < k ; j ++)                    t[j] = str[j] ;                t[k] = '\0' ;                tmp = atoi(t) ;                val = sg[tmp]  ;            }            else{                for( ; j < curr && val ; j ++){                    str[k] = j ;                    tmp = atoi(str) ;                    val = sg[tmp] ;                }            }            str[k] = curr ;        }        sg[i] = !val ;    }}int main(){    init() ;    int p  ;    int sign ;    while(scanf("%s" , str) !=EOF ){        sign = 1 ;        if(str[0] != '0'){            p = atoi(str) ;            sign = sg[p]  ;        }        if(sign)            puts("Yes") ;        else            puts("No") ;    }    return 0 ;}

hdu 1536 SG函数,跟斐波那契那道差不过的题目。

#include <stdio.h>#include <string.h>#include <stdlib.h>#define maxn 105int  si[maxn] ;int  sg[maxn * 100]  ;bool mex[maxn * 100] ;int  m ;int  n ;int cmp(const void * a , const void * b){    int *aa = (int *)a ;    int *bb = (int *)b ;    return *aa - *bb ;}void predour_sg(){    memset(sg , -1 , sizeof(sg)) ;    sg[0] = 0 ;    for(int i = 1 ; i <= 10000 ; i ++){        memset(mex , 0 , sizeof(mex)) ;        for(int j = 0 ; j < m ; j ++){            if(i - si[j] < 0)                break ;            mex[ sg[ i - si[j] ] ] = 1 ;        }        int k = 0 ;        while(mex[k ++]) ;        sg[i] = --k ;    }}int main(){    //freopen("1536.in" ,"r" , stdin) ;    while(scanf("%d" , &m) , m){        for(int i = 0 ; i < m ; i ++){            scanf("%d" , &si[i]) ;        }        qsort(si , m , sizeof(si[0]) , cmp) ;        predour_sg() ;        scanf("%d" , &n) ;        while(n--){            int k ;            int x  ;            int ans = 0 ;            scanf("%d" , &k) ;            while(k --){                scanf("%d" , &x) ;                ans = ans ^ sg[x] ;            }            if(ans)                putchar('W') ;            else                putchar('L') ;        }        putchar('\n') ;    }    return 0 ;}