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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

BZOJ 1188: [HNOI2007]分裂游戏(multi-nim)

發布時間:2024/4/15 编程问答 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BZOJ 1188: [HNOI2007]分裂游戏(multi-nim) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Time Limit:?10 Sec??Memory Limit:?162 MB
Submit:?1386??Solved:?840
[Submit][Status][Discuss]

Description

聰聰和睿睿最近迷上了一款叫做分裂的游戲。該游戲的規則試:共有n個瓶子,標號為0,1,2.....n-1,第i個瓶子中 裝有p[i]顆巧克力豆,兩個人輪流取豆子,每一輪每人選擇3個瓶子。標號為i,j,k,并要保證i<j,j<=k且第i個瓶子 中至少要有1顆巧克力豆,隨后這個人從第i個瓶子中拿走一顆豆子并在j,k中各放入一粒豆子(j可能等于k)。如 果輪到某人而他無法按規則取豆子,那么他將輸掉比賽。勝利者可以拿走所有的巧克力豆!兩人最后決定由聰聰先 取豆子,為了能夠得到最終的巧克力豆,聰聰自然希望贏得比賽。他思考了一下,發現在有的情況下,先拿的人一 定有辦法取勝,但是他不知道對于其他情況是否有必勝策略,更不知道第一步該如何取。他決定偷偷請教聰明的你 ,希望你能告訴他,在給定每個瓶子中的最初豆子數后是否能讓自己得到所有巧克力豆,他還希望你告訴他第一步 該如何取,并且為了必勝,第一步有多少種取法? 假定 1 < n < = 21,p[i] < = 10000

Input

輸入文件第一行是一個整數t表示測試數據的組數, 接下來為t組測試數據(t<=10)。 每組測試數據的第一行是瓶子的個數n, 接下來的一行有n個由空格隔開的非負整數,表示每個瓶子中的豆子數。

Output

對于每組測試數據,輸出包括兩行, 第一行為用一個空格兩兩隔開的三個整數,表示要想贏得游戲, 第一步應該選取的3個瓶子的編號i,j,k, 如果有多組符合要求的解,那么輸出字典序最小的一組。 如果無論如何都無法贏得游戲,那么輸出用一個空格兩兩隔開的三個-1。 第二行表示要想確保贏得比賽,第一步有多少種不同的取法。

Sample Input

2
4
1 0 1 5000
3
0 0 1

Sample Output

0 2 3
1
-1 -1 -1
0

HINT

Source

?

又一道神題,一開始一直在分析最后一堆和倒數第二堆,分析出了一坨沒卵用的性質

首先,我們按照套路,觀察有沒有模仿棋性質的操作,發現當豆子個數為偶數的時候后手可以把先手抵消掉

這樣的話豆子數實際就變成了一串01序列

我們此時回過頭來考慮拿豆子的操作,實際上就是一個multi-nim的模型,然后這題就可做了

因為處理的時候需要用到后面的SG函數,所以用記憶化搜索

輸出方案的話。

暴力枚舉第一個的位置,然后用異或的性質判斷一下

?

?

#include<cstdio> #include<cstring> const int MAXN=1001; inline char nc() {static char buf[MAXN*100],*p1=buf,*p2=buf;return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN*100,stdin),p1==p2)?EOF:*p1++; } inline int read() {char c=nc();int x=0,f=1;while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();}while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();}return x*f; } int N,S[MAXN],SG[MAXN];//游戲可以看做是每個位置獨立進行的 int a[MAXN]; int dfs(int now) {if(SG[now]!=-1) return SG[now];memset(S,0,sizeof(S));for(int i=now+1;i<=N;i++)for(int j=i;j<=N;j++)S[ (dfs(i)^dfs(j)) ] = 1;for(int i=0;;i++) if(!S[i]) {SG[now]=i;break;}return SG[now]; } int main() {#ifdef WIN32freopen("a.in","r",stdin);#else#endifint QwQ=read();while(QwQ--){memset(SG,-1,sizeof(SG));N=read();for(int i=1;i<=N;i++) a[i]=read();for(int i=1;i<=N;i++) if(a[i]&1) dfs(i); int ans=0,tot=0;for(int i=1;i<=N;i++) if(a[i]&1)ans=(ans^dfs(i));for(int i=1;i<=N;i++)for(int j=i+1;j<=N;j++)for(int k=j;k<=N;k++){if( (ans^dfs(i)^dfs(j)^dfs(k) )!=0) continue;tot++;if(tot==1) printf("%d %d %d\n",i-1,j-1,k-1);}if(tot==0) printf("-1 -1 -1\n");printf("%d\n",tot);}return 0; }

?

轉載于:https://www.cnblogs.com/zwfymqz/p/8469290.html

總結

以上是生活随笔為你收集整理的BZOJ 1188: [HNOI2007]分裂游戏(multi-nim)的全部內容,希望文章能夠幫你解決所遇到的問題。

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