1. 程式人生 > >HDU4315 Climbing the Hill

HDU4315 Climbing the Hill

AR scanf font scan 特殊 TP pos bit 題目

題目鏈接:https://cn.vjudge.net/problem/HDU-4315

知識點:  博弈論

題目大意:

  \(Alice\) 和 \(Bob\) 輪流指揮 \(N\) 個人爬山,這 \(N\)個人在山頂下的不同層,國王是第 \(k\) 個人。山的每一層都最多只能容納 \(1\) 個人(除了山頂),兩個玩家每次都能指揮任意一個人向上爬任意層直到山頂,但不能讓一個人越過另一個人。指揮國王爬到山頂上即可獲勝。

解題思路:

  首先,如果國王是第一個人,先手必勝。

  如果 \(N\) 是偶數,關鍵局面為:對於所有合法的 \(i\),有第 \(2i\) 個人和第 \(2i-1\) 個人相鄰。易知此時當國王是第偶數個人時後手必勝,因為無論先手怎麽操作,後手都至少能維持住這個局面,或者取得勝利;當國王是第奇數個人時也是後手必勝,後手可以維持這個關鍵局面直到國王成為第 \(3\) 個人,並繼續保持第 \(2i-1\) 和第 \(2i\) 相鄰,先手接下來遲早會被迫將第一個人移到山頂,後手下一步將第二個人移到山頂的下一個位置,這是一個後手必勝的局面。現在遊戲已經轉換成一個 \(Nim\) 博弈,石子就是第 \(2i-1\) 和第 \(2i\) 個人之間的間隔。

  如果 \(N\) 是奇數,可以在第一個人前面再想象一個人,他在山頂的再上一層,當第一個人被放到山頂的時候,二者相鄰,此時又轉換成偶數個人的情況了。有一種特殊情況是當國王是第二個人的時候,那麽想象出來的這個人就得放在山頂,當第一個人被放到山頂的下一層時二者即可相鄰,因為先手如果將第一個人直接放到山頂,那麽後手能直接取勝。

AC代碼:

 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 const int maxn=1005;
 5 int pos[maxn];
 6 int main(){
 7     int N,k;
8 while(scanf("%d%d",&N,&k)==2){ 9 for(int i=1;i<=N;i++) scanf("%d",&pos[i]); 10 if(k==1){ 11 printf("Alice\n"); 12 continue; 13 } 14 if(N%2==0){ 15 int sg=0; 16 for(int i=1;i<=N;i+=2) 17 sg^=(pos[i+1
]-pos[i]-1); 18 if(!sg) printf("Bob\n"); 19 else printf("Alice\n"); 20 } 21 else{ 22 int sg=pos[1]; 23 if(k==2) sg--; 24 for(int i=2;i<=N;i+=2) 25 sg^=(pos[i+1]-pos[i]-1); 26 if(!sg) printf("Bob\n"); 27 else printf("Alice\n"); 28 } 29 } 30 return 0; 31 }

HDU4315 Climbing the Hill