博弈論初級入門題目

詳細資料參見博弈論入門

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 1010
int 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 100
int 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 105

int  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 ;
}




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章