Codeforces Round 1073 Div1 + Div2 部分题目题解
比赛传送门:Codeforces Round 1073。
打的 Div2。AB 赛时切了。
C 题解
设 \(s\) 升序排序后为 \(t\),那么如果 \(s=t\) 显然 Bob 胜利,否则我们断言 Alice 一定胜利。
如果 Alice 可以一步将 \(s\) 变成 \(t\),那么他就赢了,而我们发现如果 Alice 操作 \(s\) 与 \(t\) 不相等那部分,显然可以将其排序,做完了。
#include<bits/stdc++.h>
#define int long long
#define double long double
using namespace std;
inline int read(){
char c=getchar();
int f=1,ans=0;
while(c<48||c>57) f=(c==45?f=-1:1),c=getchar();
while(c>=48&&c<=57) ans=(ans<<1)+(ans<<3)+(c^48),c=getchar();
return ans*f;
}
inline void solve(){
int n=read();
string s,t;cin>>s;t=s;
sort(t.begin(),t.end());
if (s==t){
puts("Bob");
return ;
}
puts("Alice");
vector<int>anss;
for (int i=0;i<n;i++) if (s[i]!=t[i]) anss.push_back(i);
printf("%lld\n",(int)anss.size());
for (auto i:anss) printf("%lld ",i+1);puts("");
}
main(){
int T=read();
while(T--) solve();
return 0;
}
D1 题解
枚举使得 \(t\) 比 \(s\) 优的位置 \(i\) 满足 \(s_i\) 为右括号,那么 \(t\) 前 \(i-1\) 与 \(s\) 前 \(i-1\) 位相同,找到第一个 \(j>i\) 满足 \(s_j\) 为左括号。
因此 \(t\) 中我们一定不能选 \(i+1\) 到 \(j\) 这些位置,为了让 \(t\) 是正则的,后面还不能选 \(j-i\) 个左括号,判一下是否有这么多即可,答案即为 \(\max\{n-2(j-i)\}\)。
证明这样的 \(t\) 是正则的,可以把左括号看成 \(1\),右括号看成 \(-1\),然后分析即可。
所以显然答案只有 \(-1\) 或 \(n-2\)。
#include<bits/stdc++.h>
#define int long long
#define double long double
using namespace std;
const int N=2e5+10;
inline int read(){
char c=getchar();
int f=1,ans=0;
while(c<48||c>57) f=(c==45?f=-1:1),c=getchar();
while(c>=48&&c<=57) ans=(ans<<1)+(ans<<3)+(c^48),c=getchar();
return ans*f;
}
int n,a[N],b[N];
inline void solve(){
n=read();
string s;cin>>s;s=" "+s;
for (int i=0;i<=n+1;i++) a[i]=b[i]=0;
for (int i=n;i>0;i--) b[i]=b[i+1]+(s[i]=='(');
a[n+1]=n+1;
for (int i=n;i>0;i--) if (s[i]=='(') a[i]=i;else a[i]=a[i+1];
int ans=-1;
for (int i=1;i<=n;i++) if (s[i]==')'&&a[i]<=n&&b[a[i]+1]>=a[i]-i) ans=max(ans,n-2*(a[i]-i));
printf("%lld\n",ans);
}
main(){
int T=read();
while(T--) solve();
return 0;
}

浙公网安备 33010602011771号