codeforces151A~D

文章介绍了Codeforces的几道算法题,涉及用特定数字表示整数的问题,两点间最短路径的最长公共部分,以及判断是否存在满足条件的字符串。解答关键在于对问题的数学建模和巧妙的编程技巧,如利用前缀和优化解法。
摘要由CSDN通过智能技术生成

codeforcesA~C

A.Forbidden Integer

在这里插入图片描述
题意:t组输入,每组输入n,k,x;求解用1-k中的数但不包括x来表示n,如果可以则输出,不可以则打印NO.

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100010 + 10;

int a[N];
signed main() {
	int t;
	cin>>t;
	while(t--){
		int n,k,x;
		cin>>n>>k>>x;
		if(x!=1){
			cout<<"YES\n"<<n<<"\n";
			while(n--) cout<<1<<" ";
			cout<<endl;
		} 
		else{
  			if(n%2==1&&k==2) cout<<"NO\n";
			  else if(n%2==0&&k>=2){
			  	int x=n/2;
			  	cout<<"YES\n";
			  	cout<<x<<endl;
			  	while(x--) cout<<2<<" ";
			  	cout<<endl;
			  } 
			  else if(n%2==1&&k>=3){
			  	cout<<"YES\n";
			  	int x=n/2;
			  	cout<<x<<endl;
			  	x--;
			  	while(x--) cout<<2<<" ";
			  	cout<<3<<endl;
			  }
			  else cout<<"NO\n";
		}
	}
 	return 0;
}

题目说有多种解,则知道可以有简便的思想:
1.如果x!=1,则可以全为一
2.若x为1,且是k>=3,则n为偶数便全用2,为奇数则最后一个233.若x为1,k==2,为奇数无解,偶数有解,全用24.若x为1,k==1,无解

B.Come Together

在这里插入图片描述
题意:三个点,A,B,C求解两个人分别从A到B和C的最短路径中的最长公共路径

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100010 + 10;

signed main() {
	int t;
	cin>>t;
	while(t--){
		int ax,ay,bx,by,cx,cy;
		cin>>ax>>ay>>bx>>by>>cx>>cy;
		int ans=1;
		 bx-=ax,by-=ay,cx-=ax,cy-=ay;
		 if((bx>0)==(cx>0)) ans+=min(abs(bx),abs(cx));
		 if((by>0)==(cy>0)) ans+=min(abs(by),abs(cy));
		 cout<<ans<<endl;
	}
 	return 0;
}

画图理解

C.Strong Password

在这里插入图片描述
题意:给出s,l,r三个字符串,m是l和r的长度,求解是否有一个新的长为m的字符串x,且li<=xi<=ri,且x不是s的子串。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100010 + 10;


signed main() {
	int t;
	cin>>t;
	while(t--){
	string s,l,r;
	int m;
	cin>>s>>m>>l>>r;
	int n=s.size();
	int net[n+1][10];
	for(int i=0;i<10;i++) net[n][i]=n;
		for(int i=n-1;i>=0;i--)
			{
				for(int j=0;j<10;j++)
					net[i][j]=net[i+1][j];
				net[i][s[i]-'0']=i;
			}
		int x=-1;
		
		for(int i=0;i<m && x < n;i++)
			{
				int y=0;
				for(int j=l[i]-'0';j<=r[i]-'0';j++)
				{
					y=max(y,net[x+1][j]);	
				} 
				x=y;
			}
		if(x==n) cout<<"YES\n";
		else cout<<"NO\n";
		
	}
 	return 0;
}

如果我们在找到的字符串中,与s重复部分越前则越容易是s的子串。
所以我们只要找到的x中的字母超出s长度的,或者是s中没有的则视为成功。
所以初始化一个二维数组表示net[i][j],表示在s字符串中的第i位上的j字母的位置。
同时初始化注意,如果第i位上不是j字母,则将后面位置的j字母的位置覆盖过来,用于更好求解。
如果都没有,则初始化为n.

D.Rating System

在这里插入图片描述
题意:给出一个数组,寻找一个k使得该数组的前缀和在达到k之后就不能再小于k了
理解:求一个连续子数组和最小,然后在此数组前的前缀和就为所求k值,所以运用前缀和的知识。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 100010 + 10;
int a[N];
signed main() {
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		cin>>n;
		int csum=0;
		int cmax=0;
		int kk=0;
		int ans;
		for(int i=0;i<n;i++)
		{
			int a;
			cin>>a;
			csum+=a;
			cmax=max(cmax,csum);
			int val=cmax-csum;
			if(val>kk){
				kk=val;
				ans=cmax;
			}
		}
		cout<<ans<<endl;
	}
		
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值