CodeTON Round 3 (Div. 1 + Div. 2, Rated, Prizes!)

比赛链接: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();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值