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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

Nim游戏的一个扩展——51nod 1661 黑板上的游戏+LA 5059 Playing With Stones

發布時間:2023/11/30 编程问答 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Nim游戏的一个扩展——51nod 1661 黑板上的游戏+LA 5059 Playing With Stones 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前幾天做過一道題目,是Nim游戲的一個擴展,也不能說擴展吧,只是說另一種常見的狀態。

問題引入:

給定n堆石子,每堆石子有vi(1<=vi<=1e5) 個,每次可以取一堆中的一些石子,使得剩下的石子為1到vi/k個,為最后的是先手勝,還是后手勝,如果先手勝則輸出相應的操作策略。

思考:

當k==2的時候,顯然就退化成了la 5059 的題目,我們以此為基礎來考慮,肯定要先計算出sg的函數表,然后觀察規律,lrj在訓練指南中說的很清楚,打表的規則也很簡單,下面給出lrj所打出的表:
0 1 0 2 1 3 0 4 2 5
當然,lrj是從奇偶性來分析的,那么很容易得出
sg(x)=n%2==0?sg(n/2)這樣的結論,因為k==2,剛好有一些特性被提現出來了。所以:

#include <bits/stdc++.h> using namespace std;typedef long long ll; ll sg(ll n) {return n%2==0 ? n/2 : sg(n/2); } int main() {int T;scanf("%d",&T);while(T--){int n;ll x;scanf("%d",&n);ll ans=0;while(n--){scanf("%lld",&x);ans^=sg(x);}if(ans)printf("YES\n");elseprintf("NO\n");}return 0; }

那么當k>2的時候,又該怎么去解決?難道比葫蘆畫瓢?要推出
sg=(n%k==0)?n/k:sg(n/k) 這樣的結論,如果真的這樣,我只能說比葫蘆畫瓢的能力只用在了記答案上,這種能力應該是一種分析該問題的方法,正確的解法無非是打sg表,尋找規律。

筆者隨手推了一下,那么打出的表如下:

k==3: 0 1 2 0 3 4 1 5 6
k==4:0 1 2 3 0 4 5 6 1 7 8 9

可以發現,都有123456……這個序列,而再去翻看上面的n==2的情況,發現都存在這樣的規律,但是,好像沒什么用,具體編程還是沒辦法操作,再去細看,發現打斷123456這個序列的的下標x都是x%k==1,而且去掉123456這樣的數后得到的都是原序列,那么,也就是說,當x%k==1時,sg(x)=sg(x/k) 否則,這樣的123456序列實際上是由x-階梯層數得到的,什么是階梯層數,當k==3的時候x=1,2,3就屬于第一層,x=4,5,6 就屬于第二層,那么容易得出:

x%k==1 ? sg(x/k) : x-x/k-(x%k!=0);

于是,上題的第二種解法為:

#include <bits/stdc++.h> using namespace std;typedef long long ll; ll k=2; ll sg(ll x){if (x==1) return 0;return x%k==1 ? sg(x/k) : x-x/k-(x%k!=0); } int main() {int T;scanf("%d",&T);while(T--){int n;ll x;scanf("%d",&n);ll ans=0;while(n--){scanf("%lld",&x);ans^=sg(x);}if(ans)printf("YES\n");elseprintf("NO\n");}return 0; }

而對于51nod中要求求必勝操作時,只需預處理一下sg值,然后枚舉每一位根據sg值來逆推符合條件的x即可。

提交地址:
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1661

#include <bits/stdc++.h> using namespace std;typedef long long ll; const int N=1e5+5;ll n,k,sl[N],sr[N],v[N],vt[N]; ll sg(ll x){if (x==1) return 0;return x%k==1 ? sg(x/k) : x-x/k-(x%k!=0); }int main() {sl[0]=sr[n+1]=0;cin>>n>>k;ll p=0,ans=0;for (int i=1;i<=n;i++){scanf("%lld",v+i);vt[i]=sg(v[i]);sl[i]=sl[i-1]^vt[i];}for (int i=n;i>=1;i--) sr[i]=sr[i+1]^vt[i];for (int i=1;i<=n;i++){ll tt=sl[i-1]^sr[i+1],tx=ceil(1.0*v[i]/k);if (v[i]==1||vt[i]<=tt) continue;ll ttl=(ll)(1.0*tt*k/(k-1)+1);if (ttl%k==1) ttl--;for (int j=0;j<64;j++){if (ttl>=tx) break;ttl=ttl*k+1;}if (ttl<v[i]&&sg(ttl)==tt){p=i;ans=ttl;break;}}if (sl[n]) cout<<"Alice "<<p<<" "<<ans<<endl;else puts("Bob"); }

總結

以上是生活随笔為你收集整理的Nim游戏的一个扩展——51nod 1661 黑板上的游戏+LA 5059 Playing With Stones的全部內容,希望文章能夠幫你解決所遇到的問題。

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