题目链接
CF1527B1(luogu)
CF1527B2(luogu)
CF1527B1(codeforces)
CF1527B2(codeforces)
解题思路
这篇题解分 B1,B2 两个部分来讲。
B1 sol:
考虑字符串中 \(0\) 的数量,设这个值为 \(sum\):
-
若 \(sum \equiv 0 \pmod{2}\),且字符串回文时,那么此时,后手可以一直模仿先手的操作,直到字符串含有最后一个 \(0\) 时,后手可以反转这个字符串,那么此时后手的代价比先手要少 \(2\),综上,后手此时必胜。
-
若 \(sum \equiv 1 \pmod{2}\),且字符串回文时,那么此时,字符串的长度一定为奇数,且字符串中间的数字一定为 \(0\),那么此时,先手可以将中间的 \(0\) 变为 \(1\),此时若还有剩余的 \(0\),则先手必胜,否则后手必胜。
综上,这就是 B1 的做法。
B2 sol:
仍然考虑字符串中 \(0\) 的数量,设这个值为 \(sum\):
若字符串已经回文,则直接按照 B1 的做法来做。
否则,先手一定可以反转字符串,直到后手把这个字符串变为回文,那么此时:
-
若 \(n \equiv 0 \pmod{2}\),由于此时先手仍然可以一直模仿后手的操作,由于前期先手比后手付出的代价要少,因此可以得出先手必胜。
-
若 \(n \equiv 1 \pmod{2}\),如果字符串中间的数字不为 \(0\) 则先手仍然可以模仿后手的情况,此时先手必胜。否则,若此时 \(sum = 2\),则后手去掉最外侧的 \(0\),此时先手与后手平局,其余情况,我们发现先手的所需代价至少比后手少 \(1\),先手必胜。
参考代码
#include<bits/stdc++.h>
using namespace std;
//#define map unordered_map
#define re register
#define ll long long
#define forl(i,a,b) for(re ll i=a;i<=b;i++)
#define forr(i,a,b) for(re ll i=a;i>=b;i--)
#define forll(i,a,b,c) for(re ll i=a;i<=b;i+=c)
#define forrr(i,a,b,c) for(re ll i=a;i>=b;i-=c)
#define pii pair<ll,ll>
#define mid ((l+r)>>1)
#define lowbit(x) (x&-x)
#define pb push_back
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
#define endl '\n'
#define QwQ return 0;
ll _t_;
void _clear(){}
ll n;
string s;
bool check(string s)
{ll L=1,R=n;while(L<=R && s[L]==s[R])L++,R--;return L>=R;
}
/*
1101011011 0:111111 1:1100110110110011011101 0:11111101 1:11011111
*/
void solve()
{_clear();cin>>n>>s;s=' '+s;if(check(s)){ll sum=0;for(auto i:s)sum+=i=='0';if(sum%2==0){cout<<"BOB\n";return ;}if(sum==1){cout<<"BOB\n";return ;}cout<<"ALICE\n";return ;}ll sum=0;for(auto i:s)sum+=i=='0';if(n%2 && sum==2 && s[(n+1)/2]=='0')cout<<"DRAW\n";elsecout<<"ALICE\n";
// exit(-1);
}
int main()
{
// freopen("tst.txt","r",stdin);
// freopen("sans.txt","w",stdout);IOS;_t_=1;cin>>_t_;while(_t_--)solve();QwQ;
}