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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

巴什博弈例题:NYOJ23;HDU:2149,1847,2897,2188

發布時間:2024/10/6 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 巴什博弈例题:NYOJ23;HDU:2149,1847,2897,2188 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

巴什博弈:

只有一堆n個物品,兩個人輪流從這堆物品中取除,每次取的個數為[1,m](至少去一個,最多取m個),最后取完者獲勝

特征:

物品只有一堆,簡單變形:

要么在范圍內不規定個數,要么規定只能取幾個?

分析:

1.如果n<=m,那么先者一定贏?

2.如果n=m+1,那么由于一次最多取m個,無論先取者拿走多少個,后者一定能夠一次拿走所有物品,后者取勝?

3.因此,我們發現了如何取勝的方法:
如果n=(m+1)*r+s;(r為任意自然數,s<=m),那么先取者拿走s個物品,后取者拿走k(k<=m)個物品,先取者再拿走(m+1-k)個物品,結果剩下(m+1)*(r-1)個物品,那么先取者一定獲勝

4.要保持給對手留下(m+1)的倍數個物品,只要n%(m+1)!=0,先取者一定獲勝

?例題:

NYOJ23取石子(一)

//hdu2149 巴什博弈 #include<bits/stdc++.h> using namespace std;int main() {ios::sync_with_stdio(false);int n,m,t;cin>>t;while(t--){cin>>n>>m;if(n%(m+1)!=0)printf("Win\n");elseprintf("Lose\n");}return 0;}

HDU2149????Public Sale

//hdu2149 巴什博弈 #include<bits/stdc++.h> using namespace std;int main() {ios::sync_with_stdio(false);int n,m;while(cin>>n>>m){if(n<=m){for(int i=n;i<m;i++)printf("%d ",i);printf("%d\n",m);}else{if(n%(m+1)==0)printf("none\n");else{bool first=1;//控制輸出格式 for(int s=1;s<=m;s++){if((n-s)%(m+1)==0){if(first){//如果是第一個元素 printf("%d",s);first=0;//已輸出第一個元素 } elseprintf(" %d");//非第一個元素,前面右一個空格 }}printf("\n");}}}return 0;}

優化之后的代碼:

1.若n>m,先取者必勝
2.若n%(m+1)!=0,那么第一個取的數就是n%(m+1);

留給對手的就是m+1的倍數?

#include<iostream> using namespace std; int main() { int n;//成本 int m;//最大加價 while(scanf("%d%d",&n,&m)!=EOF){ if(n%(m+1)==0) cout<<"none";else{ if(n%(m+1)) cout<<n%(m+1); //直接取余數 if(m>=n){ for(int i=n+1;i<=m;i++)cout<<" "<<i;} }cout<<endl;}return 0; }

Java?

import java.util.*; import java.math.*;public class Main{static int MAXN=(int)(2e5+10);public static void main(String[] args) {Scanner cin=new Scanner(System.in);while(cin.hasNext()) {int m=cin.nextInt();int n=cin.nextInt();if(m<=n) {for(int i=m;i<=n;i++) {System.out.print(i);if(i==n)System.out.println();elseSystem.out.print(" ");}continue;}if(m%(n+1)==0)System.out.println("none");else {int x=m%(n+1);System.out.println(x);}}cin.close();} }

HDU1847 巴什博弈
尋找必敗狀態,若n%3=0,則cici贏,否則kiki贏
枚舉前面幾個數,找規律

分析:

1.若留給cici的是3,那么cici只能取1個或者2個
所以下一次Kiki取后必贏
2.若是給Cici留下的是3的倍數,假設為3n(n=1,2,3,..),
那么無論Cici取什么數,剩余的數一定可以寫成3m+1或者3m+2(m<n)的形式,
那么只要Kiki再取的時候留給Cici的仍然是3的倍數的話,就必勝了?

#include<bits/stdc++.h> using namespace std;int main() {ios::sync_with_stdio(false);int n;while(cin>>n){if(n%3==0)cout<<"Cici\n";else cout<<"Kiki\n";} return 0;}

HDU2188?

import java.util.*; import java.math.*;public class Main{static int MAXN=(int)(2e5+10);public static void main(String[] args) {Scanner cin=new Scanner(System.in);int T=cin.nextInt();while((T--)!=0) {int n=cin.nextInt();int m=cin.nextInt();if(n<=m) {System.out.println("Grass");continue;}if(n%(m+1)==0) {System.out.println("Rabbit");}else {System.out.println("Grass");}}cin.close();} }

HDU 2897 巴什博弈變形

每行有三個數字n,p,q,表示一堆硬幣一共有n枚,從這個硬幣堆里取硬幣,一次最少取p枚,最多q枚,如果剩下少于p枚就要一次取完。兩人輪流取,直到堆里的硬幣取完,最后一次取硬幣的算輸。對于每一行的三個數字,給出先取的人是否有必勝策略,如果有回答WIN,否則回答LOST。

Input

不超過100000行,每行三個正整數n,p,q。

Output

對應每行輸入,按前面介紹的游戲規則,判斷先取者是否有必勝策略。輸出WIN或者LOST。

Sample Input

7 2 4

6 2 4

Sample Output

LOST

WIN

分析:

假設先取者為A,后取者為B,初始狀態下有石子n個,除最后一次外,其他每次取得石子個數必須在[p,q]之間。?

1):若當前石子共有n = (p+q) * r個,則A必勝;

必勝策略為:A第一次取q個,以后每次若B取K個,A取(p+q-k)個,如此下去;最后必剩下p個給B,所以A必勝。?

2)若n = (p+q)* r + left個(1 <= left <= p)B必勝;

必勝策略為:每次取石子活動中,若A取k個,則B去(p+q-k)個,那么最后剩下left個給A,此時left <= p,所以A只能一次去完,B勝。?

3)若n = (p+q) * r + left個(p < left <= q),則A必勝;

必勝策略為:A第一次取t(1 <= left – t < = p)個,以后每次B取k個,則A取(p+q-k)個,那么最后留下1 <= left – t <= p給B,則A勝。

(也就相當于當A取得時候,他可以把當前局勢變為第2種的,即讓B面對必敗態,這時候的原理和第2種就一樣了)

import java.util.*; import java.math.*;public class Main{static int MAXN=(int)(2e5+10);public static void main(String[] args) {Scanner cin=new Scanner(System.in);while(cin.hasNext()) {int n=cin.nextInt();int p=cin.nextInt();int q=cin.nextInt();int left=n%(p+q);if(left==0)System.out.println("WIN");else if(left<=p)System.out.println("LOST");else System.out.println("WIN");}cin.close();} }

打表代碼

#include <cstdio> #include <cstring> #include <algorithm> #include<iostream> using namespace std; const int maxn=2e5+10; int sg[maxn]; int vis[maxn]; void SG(int n,int p,int q) {int i,j;memset(sg,0,sizeof(sg));for(i=p+1; i<=n; ++i){memset(vis,0,sizeof(vis));for(j=p; j<=q; ++j)vis[sg[i-j]]=1;//標記最小的不屬于這個集合的非負整數for(j=0; j<n; ++j)if(!vis[j]){sg[i]=j;break;}}for(i=0; i<n; i++)cout<<sg[i]<<endl; } int main(){int n,p,q;while(scanf("%d%d%d",&n,&p,&q)!=EOF){SG(n,p,q);} }

?

總結

以上是生活随笔為你收集整理的巴什博弈例题:NYOJ23;HDU:2149,1847,2897,2188的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。