题目描述
难度分:1200
输入T(≤2×104)表示T组数据。所有数据的n之和≤2×105。
每组数据输入n(2≤n≤105)和长为n的数组a(1≤a[i]≤109),下标从1 开始。
Alice
和Bob
玩回合制游戏,Alice
先。
每回合,如果a1=0,那么当前玩家输掉游戏,对手获胜。
否则当前玩家把a1减少一,然后选择一个下标在[2,n]中的数字和a1交换。
双方都以最佳方式游戏,输出最后谁赢了。
输入样例
3
2
1 1
2
2 1
3
5 4 4
输出样例
Bob
Alice
Alice
算法
贪心
思维题,只要Alice
保证自己操作的不是最小值,那么每次他都可以操作完后把最小值换到前面来给Bob
操作,这样一来Bob
每次都是操作的最小值,无论他换哪个数到前面来让Alice
操作,Bob
都一直在减少最小值,所以必然是他面对将a[1]减成0的局面,Alice
此时必胜。
复杂度分析
时间复杂度
只遍历了一遍数组,检查a[1]是不是大于minni=2a[i]即可,大于就是Alice
赢,否则是Bob
赢。因此,算法的时间复杂度为O(n)。
空间复杂度
除了输入的a数组之外,只使用了有限几个变量,额外空间复杂度为O(1)。
C++ 代码
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 200010;
int T, n, a[N];
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
int a1 = 0, mn = 0;
for(int i = 1; i <= n; i++) {
scanf("%d", &a[i]);
if(i == 1) {
a1 = a[i];
}else {
if(mn == 0) mn = a[i];
else mn = min(mn, a[i]);
}
}
if(a[1] > mn) {
puts("Alice");
}else {
puts("Bob");
}
}
return 0;
}