题目大意
Alice 和 Bob 在长度为 n 的二进制字符串 s(仅包含字符 0 和 1)上进行博弈游戏。Alice 先手,双方轮流操作。
游戏规则:
-
每回合,玩家选择一个索引序列 i₁, i₂, …, iₘ(严格递增),使得这些位置的字符形成非增序列(s[i₁] ≥ s[i₂] ≥ … ≥ s[iₘ])
-
然后将这些位置的字符重新排列为非减序列(先放所有 0,再放所有 1)
-
有效移动必须严格改变字符串(即选中的字符中至少有一个 0 和一个 1)
-
无法进行有效移动的玩家输掉游戏
任务:
输入格式:
-
多组测试数据,第一行包含测试数据组数 t(1 ≤ t ≤ 10⁴)
-
每组数据:第一行为字符串长度 n(1 ≤ n ≤ 2×10⁵),第二行为二进制字符串 s
-
保证所有测试用例的 n 之和不超过 2×10⁵
输出格式:
样例说明:
-
样例 1(000):字符串已经有序,无法进行任何有效移动,Bob 直接获胜
-
样例 3(10):Alice 可以选择位置 [1,2],将字符串变为 01,之后 Bob 无法移动,Alice 获胜
思路讲解
其实我们会发现,只需要一次操作即可解决这个问题。
AC代码
AC
https://codeforces.com/contest/2191/submission/358351618
源代码
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 72 73 74 75 76 77 78
|
#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; string s; cin>>s; string sorted_str=s; sort(all(sorted_str)); vector<ll> op_ls; for (int i=0;i<N;++i) { if (sorted_str[i]!=s[i]) { op_ls.push_back(i); } } if (op_ls.empty()) { cout<<"Bob\n"; return; } cout<<"Alice\n"; cout<<SZ(op_ls)<<"\n"; for (auto pos:op_ls) { cout<<pos+1<<" "; } cout<<"\n"; }
signed main() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cin >> lT; while(lT--) Solve(); return 0; }
|
心路历程(WA,TLE,MLE……)