P2599 ZJOI2009 取石子遊戲

2022-08-23 23:27:17 字數 1631 閱讀 9736

在研究過nim遊戲及各種變種之後,orez又發現了一種全新的取石子遊戲,這個遊戲是這樣的: 有n堆石子,將這n堆石子擺成一排。遊戲由兩個人進行,兩人輪流操作,每次操作者都可以從最左或最右的一堆中取出若干顆石子,可以將那一堆全部取掉,但不能不取,不能操作的人就輸了。 orez問:對於任意給出乙個初始乙個局面,是否存在先手必勝策略。

檔案的第一行為乙個整數t,表示有 t組測試資料。對於每組測試資料,第一行為乙個整數n,表示有n堆石子;第二行為n個整數ai,依次表示每堆石子的數目。

對於每組測試資料僅輸出乙個整數0或1。其中1表示有先手必勝策略,0表示沒有。

輸入 #1

1

43 1 9 4

輸出 #1

0

資料範圍

對於30%的資料 n≤5 ai≤10^5

對於100%的資料 t≤10 n≤1000 每堆的石子數目≤10^9

by  :yybyyb

發現sg函式等東西完全找不到規律,無奈只能翻題解。

首先設l[i][j]表示在[i,j]這一段區間的左側放上一堆數量為l[i][j]的石子後,先手必敗。同理定義r[i][j]表示右側。

首先我們可以證明l[i][j]唯一,假設存在兩個l[i][j],顯然較大的那個可以通過一步轉移轉移到較小的那個,所以不合法。因此l[i][j]唯一。

接下來考慮如何證明l[i][j]一定存在。假設l[i][j]不存在,那麼對於這段區間而言,在左邊加上任意一堆石子先手都必勝,既然先手必勝意味著先手進行一步操作之後可以到達乙個必敗態,這裡分情況討論。假設先手拿的是最左邊的一堆石子,因為不存在l[i][j],所以只要拿了左邊的石子之後,當前局面都是必勝態,所以不可能拿左邊的石子。那麼只能拿右邊的石子,那麼無論右邊拿了一定量之後,無論左邊新增了多少,都是乙個必敗態,那麼此時後手在左側隨便拿走一定數量,這個狀態也還是乙個必敗態,顯然也不成立。因此l[i][j]必定存在。

綜上,我們知道了l[i][j]一定存在並且唯一,而l,r顯然是對稱的,因此r[i][j]也滿足上述性質。

現在考慮如何求解l[i][j],r[i][j]同理。首先邊界情況顯然,l[i][i]=a[i],因為只剩下兩堆一模一樣的情況的時候,後手只需要模仿先手的行動對稱執行就好了,這樣子一定不會輸,即先手必敗。

接下來來大力分類討論,為了方便,設l=l[i][j−1],r=r[i][j−1],x=a[j]

而r和l是對稱的,類似的求解即可。

那麼最終只需要判斷l[2][n]和a[1]是否相等即可判斷勝負情況。

**

#include#include#include#include#includeusing namespace std;

const int n=1010;

int t,n,a[n];

int l[n][n],r[n][n];

int main ()

for(int len=2; len<=n; len++)

for(int i=1,j=i+len-1; j<=n; i++,j++)

if(a[1]==l[2][n])

printf("0\n");

else

printf("1\n");

} return 0;

}

bzoj1413 ZJOI2009 取石子遊戲

在研究過nim遊戲及各種變種之後,orez又發現了一種全新的取石子遊戲,這個遊戲是這樣的 有n堆石子,將這n堆石子擺成一排。遊戲由兩個人進行,兩人輪流操作,每次操作者都可以從最左或最右的一堆中取出若干顆石子,可以將那一堆全部取掉,但不能不取,不能操作的人就輸了。orez問 對於任意給出乙個初始乙個局...

P2055 ZJOI2009 假期的宿舍

題目描述 學校放假了 有些同學回家了,而有些同學則有以前的好朋友來探訪,那麼住宿就是乙個問題。比如 a 和 b 都是學校的學生,a 要回家,而 c 來看b,c 與 a 不認識。我們假設每個人只能睡和自己直接認識的人的床。那麼乙個解決方案就是 b 睡 a 的床而 c 睡 b 的床。而實際情況可能非常複...

P2055 ZJOI2009 假期的宿舍

看到複雜的匹配條件,發現要讓乙個人和乙個床匹配,所以就每個有床的人 指本校學生 和t連一條邊,每個需要床的人 指外校的人和不回家的人 和s連一條邊,i和j互相認識就把i和j的床連在一起,自己和自己的床肯定連一條邊,然後流量每多1,就表示滿足了乙個人對床的需求,跑最大流就相當於最多能滿足多少人的需求,...