日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

取石子游戏与SG函数

發(fā)布時(shí)間:2024/4/11 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 取石子游戏与SG函数 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目:http://acm.hdu.edu.cn/showproblem.php?pid=1848


題意:有3堆石子,石子數(shù)量分別為a,b,c,有兩個(gè)玩家,每次只能從任意一堆中取f個(gè),這里的f只能為fibnacci數(shù),問是先手

還是先手?jǐn)?


分析:由于石子的數(shù)量都在1000以內(nèi),那么我們可以先預(yù)處理出1000以內(nèi)的SG函數(shù)值,然后對于3堆石子,我們進(jìn)行異或,如果為

0說明先手必?cái)?否則必勝,當(dāng)然求SG函數(shù)的值用深搜就行了.


#include <iostream> #include <string.h> #include <stdio.h>using namespace std; const int N = 1005; const int M = 25;int fib[25]; int SG[N];int mex(int x) {bool vis[M];memset(vis,0,sizeof(vis));for(int i=0;i<M;i++){int t = x - fib[i];if(t < 0) break;if(SG[t] == -1)SG[t] = mex(t);vis[SG[t]] = 1;}for(int i=0;;i++)if(!vis[i]) return i; }void Init() {fib[0] = 1;fib[1] = 2;for(int i=2;i<M;i++)fib[i] = fib[i-1] + fib[i-2];memset(SG,-1,sizeof(SG));for(int i=0;i<N;i++)SG[i] = mex(i); }int main() {Init();int a,b,c;while(~scanf("%d%d%d",&a,&b,&c)){if(a == 0 && b == 0 && c == 0) break;int ans = 0;ans ^= SG[a];ans ^= SG[b];ans ^= SG[c];if(ans) puts("Fibo");else puts("Nacci");}return 0; }


題目:http://acm.hdu.edu.cn/showproblem.php?pid=1536


分析:本題基本上跟上體一樣,只是把3堆改為x堆,把取fibnacci數(shù)列顆石子改為取指定輸入的石子個(gè)數(shù).那么做法實(shí)際上一

樣,我們對輸入的序列進(jìn)行排序,然后求出它們的SG函數(shù)的值,然后直接用即可.


#include <iostream> #include <string.h> #include <algorithm> #include <stdio.h>using namespace std; const int N = 10005; const int M = 105;int a[M]; int SG[N]; int n;int mex(int x) {bool vis[M];memset(vis,0,sizeof(vis));for(int i=0;i<n;i++){int t = x - a[i];if(t < 0) break;if(SG[t] == -1)SG[t] = mex(t);vis[SG[t]] = 1;}for(int i=0;;i++)if(!vis[i]) return i; }int main() {while(~scanf("%d",&n)){if(n == 0) break;for(int i=0;i<n;i++)scanf("%d",&a[i]);sort(a,a+n);memset(SG,-1,sizeof(SG));for(int i=0;i<N;i++)SG[i] = mex(i);int m;scanf("%d",&m);while(m--){int ans = 0;int len,t;scanf("%d",&len);for(int i=0;i<len;i++){scanf("%d",&t);ans ^= SG[t];}if(ans) printf("W");else printf("L");}puts("");}return 0; }


總結(jié)

以上是生活随笔為你收集整理的取石子游戏与SG函数的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。