标签:
3 3 1 2 4 2 1 100 200
Bob AliceHintThe figure illustrates the first test case. The gray cell indicates the hilltop. The circles indicate the persons, while the red one indicates the king. The first player Alice can move the person on cell 1 or cell 4 one step up, but it is not allowed to move the person on cell 2.
题意】
有N个人爬山,山顶坐标为0,其他人的坐标按升序给出。不同的坐标只能容纳一个人(山顶不限),Alice和Bob轮流选择一个人让他移动任意步,但不能越过前面那个人。现在有一个人是king(给出id),谁能将king移动到山顶就算赢。
【分析】
考虑King的情况和上述版本几乎一致,只要把King当作普通人一样处理即可。
除了两种特殊情况:
1. 当King是第一个人时,Alice直接胜
2. 当King是第二个人且一共有奇数个人时,第一堆的大小需要减1。
因为如果king在奇数石子上,那么king前面的那一对石子k1,k2.
当对方把k1移到top时,我可以把k2移到top前的一个位置.
那么对于k2石子,对方如果碰了它,那么我肯定会把king移到top的.
所以k2也相当于是一颗废子而已,不影响最终Nim的结果.
Ps:阶梯博弈学习博客链接:阶梯博弈
#pragma comment(linker, "/STACK:102400000,102400000") #include <iostream> #include <cstdio> #include <cstring> #include <stack> #include <queue> #include <map> #include <set> #include <vector> #include <cmath> #include <algorithm> using namespace std; const double eps = 1e-6; const double pi = acos(-1.0); const int INF = 1e9; const int MOD = 1e9+7; #define ll long long #define CL(a,b) memset(a,b,sizeof(a)) #define lson (i<<1) #define rson ((i<<1)|1) #define N 50010 int gcd(int a,int b){return b?gcd(b,a%b):a;} int n,k; int s[1010]; int main() { while(scanf("%d%d",&n,&k)==2) { for(int i=1; i<=n; i++) scanf("%d",&s[i]); if(k == 1) {cout<<"Alice"<<endl; continue;} int ans; if(n%2 == 0) { ans = s[2]-s[1]-1; for(int i=4; i<=n; i+=2) ans ^= (s[i]-s[i-1]-1); if(ans == 0) cout<<"Bob"<<endl; else cout<<"Alice"<<endl; } else { ans = s[1]; if(k == 2) ans -= 1; for(int i=3; i<=n; i+=2) ans ^= (s[i]-s[i-1]-1); if(ans == 0) cout<<"Bob"<<endl; else cout<<"Alice"<<endl; } } return 0; }
hdu4315 Climbing the Hill(阶梯博弈)
标签:
原文地址:http://blog.csdn.net/d_x_d/article/details/52136449