1069 nim遊戲
基準時間限制:1 秒 空間限制:131072 kb 分值: 0
難度:基礎題
有n堆石子。a b兩個人輪流拿,a先拿。每次只能從一堆中取若干個,可將一堆全取走,但不可不取,拿到最後1顆石子的人獲勝。假設a b都非常聰明,拿石子的過程中不會出現失誤。給出n及每堆石子的數量,問最後誰能贏得比賽。
例如:3堆石子,每堆1顆。a拿1顆,b拿1顆,此時還剩1堆,所以a可以拿到最後1顆石子。
input
第1行:乙個數n,表示有n堆石子。(1 <= n <= 1000)output第2 - n + 1行:n堆石子的數量。(1 <= a[i] <= 10^9)
如果a獲勝輸出a,如果b獲勝輸出b。input示例
311output示例1
a對於乙個博弈來說,p-position表示previous,代表先手必敗,即後手必勝,n-position表示next,代表先手必勝,後手必敗。
兩個博弈的結論:
若當前狀態為n,至少存在下乙個能達到的狀態是p。(1)
若當前狀態為p,則所有下乙個能達到的狀態是n。(2)
顯然(0, 0, ..., 0)為必勝態n
憑藉這樣,因此我們可以通過記憶化搜尋可以搜出答案,但是時間複雜度是n!級別的。因此需要更高效的方法來解決nim問題。
》bouton's theorem
對於乙個nim遊戲的局面(a1, a2, ..., an),它是p-position當且僅當a1 xor a2 xor... xor an=0
簡要證明:
顯然(0, 0, ..., 0)為必敗態。
可歸納證明
a)對於p-position局面(a1, a2, ..., an)滿足a1 xor a2 xor... xor an=0,對於所有合法的移動,
不妨設為新局面(a1-x, a2, ..., an),則
(a1-x) xor a2 xor ... xor an
=(a1-x) xor a2 xor ... xor an xor a1 xor a1
=(a1-x) xor a1!=0(其中a1>x)。
故滿足結論(2)
b)對於n-position局面滿足a1 xor a2 xor... xor an=k!=0,則存在乙個移動使得新局面(a1', a2', ..., an')有a1' xor a2' xor... xor an'=0。因為中存在ai的二進位制在k的最高位上為1,否則k的最高位不能得到,將ai變為ai xor k(故滿足結論(1)
故若nim遊戲局面滿足博弈的兩個結論,故存在必勝/必敗態及必勝態的必勝步驟。
至此,nim遊戲得到基本解決。
#include #include #include #include #include using namespace std;
typedef long long ll;
const int n = 1000000;
const double pi = acos(-1.0);
int main()
{ int n, x, sum=0;
scanf("%d", &n);
for(int i=0;i
51Nod 1069 Nim遊戲 nim博弈)
1069 nim遊戲 基準時間限制 1 秒 空間限制 131072 kb 分值 0 難度 基礎題 有n堆石子。a b兩個人輪流拿,a先拿。每次只能從一堆中取若干個,可將一堆全取走,但不可不取,拿到最後1顆石子的人獲勝。假設a b都非常聰明,拿石子的過程中不會出現失誤。給出n及每堆石子的數量,問最後誰...
51nod 1069 Nim遊戲(博弈)
1069 nim遊戲 基準時間限制 1 秒 空間限制 131072 kb 分值 0 難度 基礎題 有n堆石子。a b兩個人輪流拿,a先拿。每次只能從一堆中取若干個,可將一堆全取走,但不可不取,拿到最後1顆石子的人獲勝。假設a b都非常聰明,拿石子的過程中不會出現失誤。給出n及每堆石子的數量,問最後誰...
1069 Nim遊戲(51NOD基礎)
1069 nim遊戲 51nod基礎 基準時間限制 1 秒 空間限制 131072 kb 分值 0 難度 基礎題 有n堆石子。a b兩個人輪流拿,a先拿。每次只能從一堆中取若干個,可將一堆全取走,但不可不取,拿到最後1顆石子的人獲勝。假設a b都非常聰明,拿石子的過程中不會出現失誤。給出n及每堆石子...