1. 程式人生 > >【Nim博弈 && 思維】POJ

【Nim博弈 && 思維】POJ

Step1 Problem:

排成直線的格子上放有 n 個棋子。棋子 i 在左邊第 a[i] 個格子上。Georgia 和 Bob 輪流選擇一個棋子向左移動。每次可以移動一格及以上任意多格,但是不允許反超其他的棋子,也不允許將兩個棋子放在同一個格子內。
無法進行移動操作的一方失敗。假設 Georgia 先移動,當雙方都採取最優策略時,誰會獲勝?
資料範圍:
1<=n<=1000, 1<=a[i]<=10000

Step2 Ideas:

Nim博弈:
a1^a2^…^an != 0 必勝態
a1^a2^…^an == 0 必敗態
如果將棋子兩兩成對當作整體考慮,我們就可以把這個遊戲轉換成Nim遊戲。
因為成對的棋子,左邊的移動幾個格子,右邊就可以移動幾個格子,所以由它們之間的格子數量決定。
每一對棋子,之間的格子數量異或和就是結果。

Step3 Code:

#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 1e3+100;
int a[N];
int main()
{
    int T, n;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        a[0] = 0;
        for(int i = 1; i <= n; i++)
            scanf("%d", a+i);
        sort(a+1
, a+1+n); int ans = 0; for(int i = n; i >= 1; i -= 2) {//異或每一對棋子之間格子的數量 ans ^= a[i] - a[i-1] - 1; } if(ans) printf("Georgia will win\n");//必勝 else printf("Bob will win\n");//必敗 } }