Educational Codeforces Round 102 (Rated for Div. 2)部分题解(未完)

题目链接:https://codeforces.ml/contest/1473

A.Replacing Elements

贪心+排序。
先对数列进行升序排序,若输入数列中最大数小于等于d,则一定满足条件。
若最大数大于d,则可以将数列所有数字变为a[1]+a[2],比较数列中最小的两个数的和与d的大小关系即可。

#include<bits/stdc++.h>
#define ll long long
#define next next_ 
using namespace std;
int _,n,d,a[110];
int main(){
    
    
	scanf("%d",&_);
	while(_--){
    
    
		scanf("%d%d",&n,&d);
		for(int i=1;i<=n;i++) scanf("%d",&a[i]);
		sort(a+1,a+1+n);
		if(a[n]<=d) printf("YES\n");
		else if(a[1]+a[2]<=d) printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}

B.String LCM

数论GCD
设两个字符串长度为lens与lent,计算出他们的最小公倍数,再重复字符串s与t使它们长度相等,得到两个新字符串a,b。若a==b则答案存在即为a,反之答案不存在。

#include<bits/stdc++.h>
#define ll long long
#define next next_ 
using namespace std;
int _,n,d,a[110],lens,lent;
string s,t;
bool sa,sb,ta,tb;
int gcd(int a,int b){
    
    
	return b?gcd(b,a%b):a;
}
int main(){
    
    
	scanf("%d",&_);
	while(_--){
    
    
		sa=sb=ta=tb=false;
		cin>>s>>t;
		lens=s.size();
		lent=t.size();
		string a="",b="";
		int lcm=lens/gcd(lens,lent)*lent;
		for(int i=1;i<=lcm/lens;i++) a+=s;
		for(int i=1;i<=lcm/lent;i++) b+=t;
		if(a==b) cout<<a<<'\n';
		else printf("-1\n");
	}
	return 0;
}

C.No More Inversions

数学,逆序对
利用结论,山峰对称和山谷对称产生的逆序对相同,具体可以自己证明一下。
同时为了使b字典序最大,将p数列最后n-k个数字反转一下即可。

#include<bits/stdc++.h>
#define ll long long
#define next next_ 
using namespace std;
int _,n,k;
int main(){
    
    
	scanf("%d",&_);
	while(_--){
    
    
		scanf("%d%d",&n,&k);
		for(int i=1;i<=2*k-n-1;i++) printf("%d ",i);
		for(int i=k;i>=2*k-n;i--) printf("%d ",i);
		printf("\n");
	}
	return 0;
}

D.Program

区间DP
题目大意为删去指令中[l,r]的一段,求执行剩余指令的过程中x的最大值与最小值之差。
维护三个前缀数组f,maxnf,minnf表示执行完第i步时x的值与前i步过程中x的最大值与最小值(这里方便自己理解用了g数组表示倒序执行指令的过程)。
删去[l,r]的指令时,将[l,r]区间两端的指令拼接起来即可,注意l与r在边界的情况。

#include<bits/stdc++.h>
#define ll long long
#define next next_ 
using namespace std;
int _,n,m,l,r,maxnf[200010],minnf[200010],f[200010],g[200010],maxng[200010],minng[200010];
string s;
int main(){
    
    
	scanf("%d",&_);
	while(_--){
    
    
		scanf("%d%d",&n,&m);
		cin>>s;
		if(s[0]=='-'){
    
    
			f[0]=-1;
			minnf[0]=-1;
			maxnf[0]=0;
		}
		else{
    
    
			f[0]=1;
			minnf[0]=0;
			maxnf[0]=1;
		}
		for(int i=1;i<n;i++){
    
    
			if(s[i]=='-') f[i]=f[i-1]-1;
			else f[i]=f[i-1]+1;
			maxnf[i]=max(maxnf[i-1],f[i]);
			minnf[i]=min(minnf[i-1],f[i]);
		}
		for(int i=0;i<n;i++){
    
    
			g[i]=f[i]-f[n-1];
		}
		maxng[n-1]=max(0,g[n-1]);
		minng[n-1]=min(0,g[n-1]);
		for(int i=n-2;i>=0;i--){
    
    
			maxng[i]=max(maxng[i+1],g[i]);
			minng[i]=min(minng[i+1],g[i]);
		}
		while(m--){
    
    
			scanf("%d%d",&l,&r);
			l--;r--;
			if(l==0&&r==n-1) printf("1\n");
			else if(l==0) printf("%d\n",maxng[r]-g[r]-(minng[r]-g[r])+1);
			else if(r==n-1) printf("%d\n",maxnf[l-1]-minnf[l-1]+1);
			else{
    
    
				if(s[r+1]=='-') printf("%d\n",max(maxnf[l-1],maxng[r+1]-(g[r+1]-f[l-1])-1)-min(minnf[l-1],minng[r+1]-(g[r+1]-f[l-1])-1)+1);
				else printf("%d\n",max(maxnf[l-1],maxng[r+1]-(g[r+1]-f[l-1])+1)-min(minnf[l-1],minng[r+1]-(g[r+1]-f[l-1])+1)+1);
			}
		}
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_50808324/article/details/112694969