Codeforces Round #797(div3)

A. Print a Pedestal (Codeforces logo?)

题意:将一个数n分成三部分,中间最大,第二大是左边,最小是右边,详见代码

C++代码:

#include<iostream>
using namespace std;
int main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		int k=n%3;
		if(k==0){
			cout<<n/3<<" "<<n/3+1<<' '<<n/3-1<<endl;
		}else if(k==1){
			cout<<n/3<<' '<<n/3+2<<' '<<n/3-1<<endl;
		}else{
			cout<<n/3+1<<' '<<n/3+2<<' '<<n/3-1<<endl;
		}
	}
 }

B. Array Decrements

题意:给定两个数组a,b,每次可以对数组a进行如下操作:将a的每个数减一(0减去1还是0);求a是否能通过该操作变成b(没有操作次数的限制)

C++代码如下:

#include<iostream>
using namespace std;
const int N=50010; 
int a[N],b[N];
int main(){
	int t;
	cin>>t;
	while(t--){
		int n,maxx=0,flag=0;
		cin>>n;
		for(int i=1;i<=n;i++)cin>>a[i];
		for(int j=1;j<=n;j++){
			cin>>b[j];
			maxx=max(maxx,a[j]-b[j]);//求a[i]-b[i]最大的差
		}
		for(int i=1;i<=n;i++){
			if(b[i]==0&&a[i]-b[i]<=maxx&&a[i]-b[i]>=0)continue;
			else if(b[i]!=0&&a[i]-b[i]==maxx)continue;
			else{
				flag=1;
				break;
			}
		}
		if(flag)puts("NO");
		else puts("YES");
	}
	return 0;
}

C. Restoring the Duration of Tasks

题意:求出每个任务运行的时间,详见代码

C++代码如下:

#include<iostream>
using namespace std;
const int N=200010;
int s[N],f[N];
int main(){
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		for(int i=1;i<=n;i++)cin>>s[i];
		for(int i=1;i<=n;i++)cin>>f[i];
		for(int i=1;i<=n;i++)cout<<f[i]-max(s[i],f[i-1])<<" ";
		cout<<endl;
	}
	return 0;
}

D. Black and White Stripe

题意:给定一个只包含‘W’和'B'的字符串s,找出一个长度为k的子串,使得将它全部变成'B'所需要改变的’W'最少

1、设置一个数组cnt[],cnt[i]记录s[i]及其之前所出现的’W'的个数,cnt[i]=cnt[i-1]+(s[i]=='W')

2、遍历字符串s,同时更新cnt,当i>=k时,更新答案minn=min(minn,cnt[i]-cnt[i-k])

cnt[i]-cnt[i-k]即为s中下标为i-k+1~i的长度为k的子串中'W'的个数

C++代码如下:

#include<iostream>
using namespace std;
const int N=200010;
int cnt[N];//cnt[i]记录s[i]及其之前所出现过的'W'的个数
int main(){
	int t;
	cin>>t;
	while(t--){
		int n,k,minn=1e9;//minn记录最少需要将几个白色变成黑色
		cin>>n>>k;
		for(int i=0;i<=n;i++)cnt[i]=0;
		string s;
		cin>>s;
		s=' '+s;
		for(int i=1;i<s.size();i++){
			cnt[i]=cnt[i-1]+(s[i]=='W');
			if(i>=k)minn=min(minn,cnt[i]-cnt[i-k]);//如果i>=k,则更新minn
		}
		cout<<minn<<endl;
	}
	return 0;
}

E. Price Maximization

题意:将一个有n个数(n为偶数)的数组a[]分成n/2份,每份两个数,求(每一份的和/k)加起来的最大值,变量sum记录答案,初始化为0

1、输入数组时边做:sum+=a[i]/k,a[i]%=k,然后数组a每个数都存的是对k的余数

2、对数组a进行从大到小排序

3、i=1,j=n,双指针判断两个数能否结合成一组,如果a[i]+a[j]>=n,则表示可以结合,此时i++,j--,sum++(sum只加一因为a[i]+a[j]一定小于2*n),如果不能结合,j就往前移(不把i往后移是因为a[i+1]+a[j]<=a[i]+a[j],即更不可能结合),直到i和j相遇

C++代码如下:

#include<iostream>
#include<algorithm>
using namespace std;
const int N=200010;
int a[N];
bool cmp(int a,int b){
	return a>b;
}
int main(){
	int t;
	cin>>t;
	while(t--){
		int n,k;
		long long sum=0;//记得开long long,不然会爆int
		cin>>n>>k;
		for(int i=1;i<=n;i++){
			cin>>a[i];
			sum+=a[i]/k;
			a[i]%=k;
		}
		sort(a+1,a+n+1,cmp);
		int i=1,j=n;
		while(i<j){//双指针进行匹配
			if((a[i]+a[j])/k)i++,j--,sum++;
			else j--;
		}
		cout<<sum<<endl;
	}
	return 0;
}

剩下两题不T_T

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值