Codeforces Round #826 (Div. 3)——A、B、C、D

比赛链接:https://codeforces.com/contest/1741

A:

​ 

题意:比较两个字符串的大小,其大小规则满足:

方法:分类讨论

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
string a,b;
int t;

int main(){
	cin>>t;
	while(t--){
		cin>>a>>b;
		int la=a.size(),lb=b.size();
		if(a==b) cout<<"=\n";
		else if(a[la-1]==b[lb-1]&&a[la-1]=='S'){
			if(la>lb) cout<<"<\n";
			else if(la==lb) cout<<"=\n";
			else cout<<">\n";
		}
		else if(a[la-1]==b[lb-1]&&a[la-1]=='L'){
			if(la>lb) cout<<">\n";
			else if(la==lb) cout<<"=\n";
			else cout<<"<\n";
		}
		else{
			if(a[la-1]=='L'&&(b[lb-1]=='M'||b[lb-1]=='S')||a[la-1]=='M'&&b[lb-1]=='S') 
               cout<<">\n";
			else if(b[lb-1]=='L'&&(a[la-1]=='M'||a[la-1]=='S')||b[lb-1]=='M'&&a[la-1]=='S'){
				cout<<"<\n";
		}
	}
}
}

 B:

 

 题意:给出一个数组的长度N,问是否能构造“数组中相邻元素至少有一个差值为1的数组”

样例1解释:

N=4   数组:【3 4 2 1】。(我们用idx表示数组下标)

idx=1时,其右边满足|a【idx】-a【idx+1】|=1

idx=2时,其左边满足|a【idx】-a【idx-1】|=1

idx=3时,其右边满足|a【idx】-a【idx+1】|=1

idx=4时,其左边满足|a【idx】-a【idx-1】|=1

方法:通过分析样例,我们发现,只需要将1-n个元素依次进行错位就行。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
int t;
int n;

int main(){
	cin>>t;
	while(t--){
		cin>>n;
		if(n==3){
			cout<<"-1\n";continue;
		}
		cout<<n<<" "<<n-1<<" ";
		for(int i=1;i<=n-2;i++) cout<<i<<" ";
		cout<<"\n";
	}
}

 C:

 题意:给一个长度为N的数组,问是否能够分成若干段,使每段的sum相等,定义Thinkeness为若干段中,长度最长的的值,求Min(Thinkness)。

 方法:枚举。假设N=3,依次枚举区间1-1,1-2,1-3,sum的值。以该值进行后面区间的划分,如果能够划分若干个sum值相等的区间,则记录一次Thinkness,枚举中可能会产生多个区间,只需要每次取Thinkness,最后再取Min(Thinkness)。

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
typedef long long ll;
int t,n;
int a[N],sum[N];

int main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	cin>>t;
	while(t--){
		cin>>n;
		for(int i=1;i<=n;i++) cin>>a[i];
		for(int i=1;i<=n;i++) sum[i]=sum[i-1]+a[i];//前缀和
		int ans=n;
		for(int i=1;i<=n;i++){
			int ok=1,now=0,x=i,c=0;
/*ok表示这个区间是否可行,now表示每个区间段的总值,x表示第一个区间的长度,c统计区间长度*/
			for(int j=1;j<=n;j++){
				now+=a[j],c++;
				if(now>sum[i]){
					ok=0;break;
				}
				if(now==sum[i]){
					x=max(x,c);//取最大区间
					now=0;c=0;//归零
				}
			}
			if(now>0) ok=0;//最后一个区间存在,且不满足条件
			if(ok) ans=min(ans,x);//取所有情况的Min(Thinkness)
		}
		cout<<ans<<"\n";
	}
}

 D:

题意:给一棵完全二叉树,可以交换某个父节点的两个儿子,求使叶子节点单调递增的最小步数。

样例1第四步后结果为:

 方法:分治

若【L,mid】有大于【mid,R】的值,则就交换一次,然后交换完之后,再与最终结果进行比对,如果能够形成从左到右的单调递增序列,则输出ans,否则输出-1。

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3e5+10;
int a[N],b[N];
int ans,n;

void dfs(int L,int R){
	if(L==R) return;
	int mid=L+R>>1;
	dfs(L,mid),dfs(mid+1,R);
	if(a[L]>a[R]){
		ans++;
		for(int i=L;i<=mid;i++) swap(a[i],a[i+(R-L)/2+1]);//交换区间里面的左右部分
	}
}

void solve(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];b[i]=a[i];
	}
	sort(b+1,b+1+n);
	ans=0;dfs(1,n);
	for(int i=1;i<=n;i++)
		if(a[i]!=b[i]){
			cout<<"-1\n";return;
		}
	cout<<ans<<"\n";
}

signed main(){
	int T;cin>>T;
	while(T--){
		solve();
	}
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值