题目大意
这道题是 Alice 和 Bob 的博弈游戏题。
游戏规则:
-
两人在一个长度为 n 的数组上进行游戏,数组只包含 0 和 1
-
Alice 先手,双方轮流操作
-
每次操作选择区间 [l, r],将该区间替换为单个数字 1−min(al,...,ar)
-
如果区间全是 1,则替换为 0;否则替换为 1
-
游戏持续到数组只剩一个数字为止
获胜条件:
-
如果最终剩下的数字是 0,Alice 获胜
-
否则 Bob 获胜
输入格式:
-
第一行:测试用例数 t (1 ≤ t ≤ 100)
-
每个测试用例第一行:数组长度 n (3 ≤ n ≤ 100)
-
每个测试用例第二行:n 个整数 a_i (0 ≤ a_i ≤ 1)
输出格式:
- 对于每个测试用例,输出 “Alice” 或 “Bob”(大小写不敏感)
要求: 判断在双方最优策略下谁会获胜
思路讲解
这种题目一般是这样的,看起来这个操作非常复杂,但是实际上是只需要很少轮次的最优操作,就可以得出答案。`
首先,如果整个序列都是1,Alice 就可以通过对整个序列进行操作立即获胜。
注意最后一次操作必须涉及至少一个a1或an。我们根据a1和an的值进行讨论:
如果a1=1,那么Alice 可以直接在区间[2,n]上操作以获胜,因为a2∼n必须包含至少一个0。
如果an=1,那么Alice 可以直接在区间[1,n−1]上操作以获胜,因为a1∼n−1必须包含至少一个0。
如果a1=0且an=0,那么在整个序列上进行操作肯定会导致Alice 失败。这意味着Alice 不能同时操作a1和an。因此,在Alice 操作后,序列a中仍然至少会有一个0。Bob 然后可以在整个序列上操作以获胜。因此,在这种情况下,Bob 获胜。(这么讲有点奇怪,其实就是,你无论第一次你怎么操作,第二次 Bob 都可以直接掀桌子,得到 1)
时间复杂度:O(∑n)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| void Solve() { ll N; cin >> N; vector<ll> A(N); for (int i=0;i<N;++i) { cin>>A[i]; } if (find(all(A),0)==A.end()) { cout<<"Alice\n"; return; } if (A.front() || A.back()) { cout<<"Alice\n"; return; } cout<<"Bob\n"; }
|
AC代码
AC
https://codeforces.com/contest/2183/submission/358031419
源代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
|
#include <bits/stdc++.h> #include <ranges> #define all(vec) vec.begin(),vec.end() #define lson(o) (o<<1) #define rson(o) (o<<1|1) #define SZ(a) ((long long) a.size()) #define debug(var) cerr << #var <<":"<<var<<"\n"; #define cend cerr<<"\n-----------\n" #define fsp(x) fixed<<setprecision(x)
using namespace std;
using ll = long long; using ull = unsigned long long; using DB = double; using LD = long double;
using CD = complex<double>;
static constexpr ll MAXN = (ll)1e6+10, INF = (1ll<<61)-1; static constexpr ll mod = 998244353; static constexpr double eps = 1e-8; const double pi = acos(-1.0);
ll lT;
void Solve() { ll N; cin >> N; vector<ll> A(N); for (int i=0;i<N;++i) { cin>>A[i]; } if (find(all(A),0)==A.end()) { cout<<"Alice\n"; return; } if (A.front() || A.back()) { cout<<"Alice\n"; return; } cout<<"Bob\n"; }
signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cin >> lT; while(lT--) Solve(); return 0; }
|
心路历程(WA,TLE,MLE……)