(Training 3)Educational Codeforces Round 102

能力不够只写了前4题 第四题在赛后10来分钟才调出来 又又又要掉分了

A. Replacing Elements

题意: 你可以做任意次操作 操作方法为选择 ai aj 使得 ak=ai+ak
问你能不能 使得数组全部小于d
思路:从前往后递推即可 只需要找出 是否存在2个数相加小于等于d 或者所有值都小于等于d

#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int main(){
    
    
	int T;
	cin>>T;
	while(T--){
    
    
		int n,k;
		scanf("%d%d",&n,&k);
		priority_queue<int, vector<int>, greater<int>>  q;
		int flag=1;
		for(int i=1;i<=n;i++){
    
    
			int x;
			scanf("%d",&x);
			q.push(x);
			if(x>k)flag=0;
		}
		int x1=q.top();
		q.pop();
		int x2=q.top();
		if(x1+x2<=k||flag)puts("YES");
		else puts("NO");
	}
	return 0;
}

B. String LCM

题意:是否能有 ax=by然后输出a*x
思路:首先判断是否可行 即字符串是否有循环节 即是否存在a+b==b+a
然后通过LCM最大公倍数 输出结果即可

#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
int gcd(int x,int y){
    
    
    return y ? gcd(y,x%y) : x;
}
int lcm(int a,int b)
{
    
    
    return a/gcd(a,b)*b;
}
int main(){
    
    
	int T;
	cin>>T;
	while(T--){
    
    
		string a,b;
		cin>>a>>b;
		if(a+b==b+a){
    
    
			int l1=a.size(),l2=b.size();
			int g=lcm(l1,l2);
			for(int i=1;i<=g/l1;i++)
			cout<<a;
			puts("");
		}
		else puts("-1");
	}
	return 0;
}

C. No More Inversions

题意:b数组为 p[a] 即 b1 b2 b3 为p[a1] p[a2] p[a3]
在满足b数组逆序对不超过a的情况下 b的字典序最大
思路:找规律 一开始我看假题 以为是p与a比 p的字典序最大 花了很长时间
后续草稿纸上写了几个 盲猜结论过了 血亏

#include<iostream>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
using namespace std;
int gcd(int x,int y){
    
    
    return y ? gcd(y,x%y) : x;
}
int lcm(int a,int b)
{
    
    
    return a/gcd(a,b)*b;
}
 
int main(){
    
    
	int T;
	cin>>T;
	while(T--){
    
    
		int n,k;
		cin>>n>>k;
		int nk=n-k;
		for(int i=1;i<k-nk;i++){
    
    
			printf("%d ",i);
		}
		for(int i=k;i>=k-nk;i--)
		printf("%d ",i);
		cout<<endl;
	}
	return 0;
}

D - Program

题意x从0开始 给出一段字符串从前往后一次进行操作
+为+1 -为-1
问 在忽略掉l到r区间后 有多少种数字
思路:区间问题首先想到了线段树 但是我没想到线段树的解法 后来发现从前处理一次 然后从后处理一次 维护最大每一位的差值 从后往前处理的是 从i到n的max 和 min 从前往后处理的是从1到 i 的max和min
其中在从后往前转移时 需要用一个额外的数组进行转移 赛时就是这里出了点问题

#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=3e5+10;
int max1[N],min1[N],max2[N],min2[N],sum1[N],max21[N],min21[N];
char s[N];
int main(){
    
    
	int T;
	cin>>T;
	while(T--){
    
    
		memset(min1,0,sizeof min1);
		memset(max1,0,sizeof max1);
		memset(min2,0,sizeof min2);
		memset(max2,0,sizeof max2);
		memset(min21,0,sizeof min2);
		memset(max21,0,sizeof max2);
		memset(sum1,0,sizeof sum1);
		int n,k;
		cin>>n>>k;;
		scanf("%s",s+1);
		int sum=0;
		for(int i=1;i<=n;i++){
    
    
			char op=s[i];
			if(op=='-')
			sum--;
			else sum++;
			min1[i]=min(min1[i-1],sum);
			max1[i]=max(max1[i-1],sum);
			sum1[i]=sum;
		}
		sum=0;
		for(int i=n;i>=1;i--){
    
    
			char op=s[i];
			if(op=='-')
			sum--;
			else sum++;
			max21[i]=max(sum,max21[i+1]);
			min21[i]=min(sum,min21[i+1]);
			min2[i]=min(min(0,sum),sum-max21[i+1]);
			max2[i]=max(max(sum,0),sum-min21[i+1]);
		}
		for(int i=1;i<=k;i++){
    
    
			int l,r;
			scanf("%d%d",&l,&r);
			int ans=max1[l-1]-min1[l-1]+1;
			int now = sum1[l-1];
			if(now+max2[r+1]>max1[l-1])ans+=now+max2[r+1]-max1[l-1];
			if(now+min2[r+1]<min1[l-1])ans+=min1[l-1]-now-min2[r+1];
			printf("%d\n",ans);
		}
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_45663216/article/details/112658038