比赛链接:https://codeforces.com/contest/1750
A:
题意:给定长度为N的序列,你可以执行以下操作任意次
1:选择三个下标 i,j,k(1<i<j<k<n)
2:如果ai>ak,ai=ai+aj,否则swap(aj,ak)
问能否将序列换成不降序列
分析:其实看样例也能发现规律。那就是,序列的第一个元素为1,就能实现,否则就不能实现。
证明:我们发现,如果序列第一个元素为1,则一定是整个序列最小的数,所以就可以一直交换aj和ak,那么我们肯定是能够将序列转变为不降序列的。如果序列第一个元素不为1,则最小的元素一定在后面(除了第一个位置的任意位置),那么我们是不可能通过操作将1放在第一个位置上的,因此就不能实现不降序列。即证!
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
int a[N];
inline void solve(){
int n;cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
if(a[1]==1) cout<<"Yes\n";
else cout<<"No\n";
}
signed main(){
int t;cin>>t;
while(t--) solve();
}
B:
题意:给定一个长度为n的01串,定义一个串的价值为:如果串中存在0和1,那么价值为0和1个数的乘积,否则是某一种数数量的平方。求原串的某一连续子串的最大价值。
分析:我们发现,最大值只有三种情况才能取得:
(我们定义一个串中0的个数为a,1的个数为b)
1:max=a*b
2:max=x*x (x为串中0连续的最大长度)
3:max=y*y(y为串中1连续的最大长度)
所以我们只需要枚举串中这三个值即可
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10;
string s;
inline void solve(){
int n;cin>>n>>s;
int a=0,b=0;
for(int i=0;i<=n-1;i++)
if(s[i]=='0') a++;
else b++;
int maxx=a*b;
a=0,b=0;int x,y;
for(int i=0;i<=n-1;){
while(s[i]=='0') a++,i++;
x=a*a;a=0;
while(s[i]=='1') b++,i++;
y=b*b;b=0;
maxx=max(maxx,max(x,y));
}
cout<<maxx<<"\n";
}
signed main(){
int t;cin>>t;
while(t--) solve();
}
C:
题意:给定两个长度都为n的01串a和b。每次我们可以对串进行操作,每次操作选择一段区间[l, r],使得a串[l, r]范围内的01翻转,b串除了[l, r]范围内的01翻转,请问能否将ab串置0,并输出方案。
分析:这里引用splay的题解吧,讲的挺好的。
代码:
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int,int> PII;
const int N=2e5+10;
inline void solve(){
int n;cin>>n;
string s1,s2;cin>>s1>>s2;
s1="*"+s1;s2="*"+s2;
int cnt=0,cnt1=0,cnt2=0;
for(int i=1;i<=n;i++){
if(s1[i]==s2[i]){//统计相同位置的字符情况
if(s1[i]=='0') cnt1++;//为0的个数
else cnt2++;//为1的个数
}
else cnt++;//统计相同位置不同字符的个数
}
if(cnt!=0&&cnt!=n){
cout<<"NO\n";return;
}
if(cnt1==n){//全为0的情况
cout<<"YES\n";
cout<<"0\n";
return;
}
if(cnt2==n){//全是1
cout<<"YES\n";
cout<<2<<"\n";
cout<<1<<" "<<1<<"\n";
cout<<2<<" "<<n<<"\n";
return;
}
vector<PII>ans;
int cur=0;
if(cnt) cur++;
for(int i=1;i<=n;i++){
if(s1[i]=='1'){
ans.push_back({i,i});
cur++;
}
}
if(cur&1){
ans.push_back({1,1});
ans.push_back({2,n});
ans.push_back({1,n});
}
cout<<"YES\n";
cout<<ans.size()<<"\n";
for(auto i:ans) cout<<i.first<<" "<<i.second<<"\n";
}
signed main(){
int t;cin>>t;
while(t--) solve();
}