标签:example 题意 第一个 red nss sam span ... cannot
2 3 1 2 3 8 1 5 6 7 9 12 14 17Sample Output
Bob will win Georgia will win
题意:给你一个 1 * n 的棋盘,里面在不同的位置放置着棋子,每次只能将一个位置棋子向前移动若干个位置,但不能超出前一个棋子的位置,当一个人在面对棋盘不能在移动时,就表示这个人输掉了比赛。
思路分析 :这个问题也叫作阶梯博弈,即将两个两个位置捆绑在一起,相邻的两个位置之间的空格数量视为袋中石子的数量,从而转变为Nim 问题。当一对棋子的后一个向前移动,代表袋中石子的数量变少,当前一个棋子向前移动,代表袋中石子数量增加,这时下一个玩家只要将后一个棋子向前移动相同的位置,即回到了最初的状态。
如果棋子的个数是奇数个的话,就将第一个棋子和棋盘捆绑即可。
我们可能还会考虑一种情况,就是某个玩家故意破坏,使得问题无法转换为取石子,例如前一个人将某对中的前者左移,而当前玩家不将这对中的另一移动,则会导致本堆石子增多了,不符合nim。但是这种情况是不会出现的。因为赢家只要按照取石子进行即可获胜,而输家无法主动脱离取石子状态。如果输家想要让某堆石子增多,那么赢家只需要让该堆减少回原状,这样输家又要面临跟上一回合同样的局面。
代码示例:
int a[1005];
int main() {
//freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
int t, n;
cin >> t;
while(t--){
scanf("%d", &n);
for(int i = 1; i <= n; i++){
scanf("%d", &a[i]);
}
sort(a+1, a+1+n);
int s, p;
if (n%2) s = a[1]-1, p = 2;
else s = 0, p = 1;
for(int i = p; i <= n; i += 2){
s ^= (a[i+1]-a[i]-1);
}
if (s!= 0) printf("Georgia will win\n");
else printf("Bob will win\n");
}
return 0;
}
标签:example 题意 第一个 red nss sam span ... cannot
原文地址:https://www.cnblogs.com/ccut-ry/p/9001675.html