HDU 1848 Fibonacci again and again(博弈)
生活随笔
收集整理的這篇文章主要介紹了
HDU 1848 Fibonacci again and again(博弈)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=1848
題意:游戲規則如下:
1、??這是一個二人游戲;
2、??一共有3堆石子,數量分別是m, n, p個;
3、??兩人輪流走;
4、??每走一步可以選擇任意一堆石子,然后取走f個;
5、??f只能是菲波那契數列中的元素(即每次只能取1,2,3,5,8…等數量);
6、??最先取光所有石子的人為勝者;
思路:我們需要找到一個新的函數f,對于局面 S=(a1,a2,a3,……an),#S=f(a1)+f(a2)+……+f(an)。若#S不等于0,則先手必勝,否則后手必勝。得到的結論是:設$S(x)表示x的下一步所有可能的局面,$S(x)={S1,S2,……Sk},g(x)={#S1,#S2,……,#Sk}。那么f(x)=mex{g(x)},也就是這樣的f滿足#S=0,則對于S的任意后繼狀態T,#T!=0;#S!=0,則存在一個后繼T,#T=0。
?
#include <iostream>#include <cstdio>#include <vector>#include <string.h>using namespace std;int n,m,p;int f[1005];void init(){vector<int> V;int i,j;V.push_back(1);V.push_back(2);while(V[V.size()-1]<=1000){i=V[V.size()-1];j=V[V.size()-2];V.push_back(i+j);}f[0]=0;f[1]=1;int visit[1005];for(i=2;i<=1000;i++){memset(visit,0,sizeof(visit));for(j=0;j<V.size()&&V[j]<=i;j++){visit[f[i-V[j]]]=1;}for(j=0;visit[j];j++);f[i]=j;}}int main(){init();while(scanf("%d%d%d",&m,&n,&p),m||n||p){int x=f[m]^f[n]^f[p];if(x) puts("Fibo");else puts("Nacci");}return 0;}
?
總結
以上是生活随笔為你收集整理的HDU 1848 Fibonacci again and again(博弈)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tornado异步请求非阻塞
- 下一篇: CSS Image Rollovers翻