2021牛客寒假算法基础集训营1补题

补题,顺便想吐槽一下,这真的是小白入门训练赛?体验真不好。可能太菜了=~=

A串

原题链接

f[1]=0,f[2]=1;
	i>=3:
	前面有us,对于第i个随便填 
		f[i]=26*f[i-1]
	前面没有us,但是有一部分u,我们填上s(例如前i个有uuu这个在i-1并没有被算进去,那加上个s就满足条件了)
		f[i]=26^(i-1)-25^(i-1)-f[i-1]	
       还有个坑,每次结果必须+mod,不然可能出现负数
#include<bits/stdc++.h>

using namespace std;
typedef long long ll;
const int N=5e6+5,mod=1e9+7;
ll f[N];
ll q_pow(ll a,ll b)
{
	ll ans=1;
	while(b){
		if(b&1)ans=(ans*a)%mod;
		a=(a*a)%mod;
		b>>=1;
	}
	return ans;
}
int main()
{
	int n;
	cin>>n;
	f[2]=1;
	ll ans=0;
	ans+=f[2];
	for(int i=3;i<=n;i++){
		f[i]=(f[i-1]*26+q_pow(26,i-1)-q_pow(25,i-1)-f[i-1]+mod)%mod;//+mod这里并不是溢出,而是保证不能为负数 
		ans=(ans+f[i])%mod;
	}
	cout<<ans<<'\n';
  return 0;
}

B括号

原题链接

构造非空字符串,要求正好含k个不同合法括号对

思路:写这题写吐了,构造长度不超过1e5。一直想不出来最短构造方法,后来往根号那里想了一下才明白。首先满足a*b=k即可,但是必须要求a+b<=1e5,如果非质数,那还行,但是遇到大质数,就不行了(构造不出来a*b=k)。那就构造 a*b+x=ka=sqrt(k),t=k%a,b=a+t/a,x=t%a。其中a*b很好解决,(())这种即可,剩下x放在a个数的前边就行。

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
int main()
{
	int n;
	cin>>n;
	if(n==0){
		cout<<"(";
	}else if(n==1){
		cout<<"()";
	}else{
		int a=sqrt(n);
		if(a*a==n){
			for(int i=1;i<=a;i++)cout<<'(';
			for(int i=1;i<=a;i++)cout<<')';
		}else{
			int x=n-a*a;
			int b=a+x/a;
			int t=x%a;
			cout<<'(';
			for(int i=1;i<=t;i++)cout<<')';
			for(int i=2;i<=a;i++)cout<<'(';
			for(int i=1;i<=b;i++)cout<<')';
			//cout<<'\n';
			//cout<<a+b<<'\n';
		}
		
	}
	cout<<'\n';
  return 0;
}
// ()()


C红和蓝

原题链接

#include<bits/stdc++.h>

using namespace std;
const int N=1e5+5;
vector<int>e[N];
int cnt,f[N],col[N];
bool flag=true;
void dfs(int u,int fa)
{
	if(!flag)return;
	int son=0;
	for(int i=0;i<e[u].size();i++){
		int v=e[u][i];
		if(v==fa)continue;
		son++;
		dfs(v,u);
	}
	if(son==0||f[u]==0){
		if(f[fa]!=0){flag=false;return;};
		f[u]=f[fa]=++cnt;
	}
}
void dfs2(int u,int fa)
{
	for(int i=0;i<e[u].size();i++){
		int v=e[u][i];
		if(v==fa)continue;
		if(f[u]==f[v]){
			col[v]=col[u];
		}else col[v]=col[u]^1;
		dfs2(v,u);
	}
}
int main()
{
	int n,u,v;
	cin>>n;
	for(int i=0;i<n-1;i++){
		cin>>u>>v;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	dfs(1,0);
	if(!flag||f[0]){
		cout<<"-1";
		return 0;
	}
	col[1]=1;
	dfs2(1,0);
	for(int i=1;i<=n;i++){
		if(col[i])cout<<"R";
		else cout<<"B";
	}
	cout<<'\n';
  return 0;
}

F对答案一时爽

原题链接

这才是签到题…

#include<bits/stdc++.h>

using namespace std;
const int N=1e3+5;
char a[N],b[N];
int main()
{
	int n;
	char c;
	cin>>n;
	for(int i=1;i<=n;i++)
		cin>>a[i];	
	for(int i=1;i<=n;i++)cin>>b[i];
	int maxx=0;
	for(int i=1;i<=n;i++){
		if(a[i]==b[i]){
			maxx+=2;
		}else{
			maxx+=1;
		} 
	}
	cout<<maxx<<' '<<0<<'\n';
//	for(int i=1;i<=n;i++)cout<<a[i]<<'\n';
	return 0;
}

I限制不互素对的排列

原题链接

构造题真恶心。给你n,构造一个排列,让你构造其中恰好有k个相邻的数gcd>1。

思路:对于k<n/2的情况,我们构造k+1个偶数即可,因为n个数有n/2个偶数,那么他一定满足要求。k==n/2的情况,因为最多有n/2个偶数,这些偶数构造出来最多能有n/2-1对满足要求,需要再增加一个,那么我们找3和6。每次让6在最后然后3排在6后面就行。另需要特判n<=5的情况

#include<bits/stdc++.h>

using namespace std;
const int N=1e5+5;
int vis[N];
int main()
{
	int n,k;
	cin>>n>>k;
	if(n<=5){
		if(k==n/2)cout<<"-1";
		else{
			for(int i=1;i<=k+1;i++){
				cout<<2*i<<' ';
				vis[2*i]=1;
			}
			for(int i=1;i<=n;i++)if(!vis[i])cout<<i<<' ';
		}
	}else{
		if(k==n/2){
			for(int i=1;i<=k;i++){
				if(2*i==6)continue;
				cout<<2*i<<' ';
				vis[2*i]=1;
			}
			cout<<6<<' '<<3<<' ';vis[3]=vis[6]=1;
			for(int i=1;i<=n;i++)if(!vis[i])cout<<i<<' ';
		}else{
			for(int i=1;i<=k+1;i++){
				cout<<2*i<<' ';
				vis[2*i]=1;
			}
			for(int i=1;i<=n;i++)if(!vis[i])cout<<i<<' ';
		}
	}
	cout<<'\n';
  return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43566782/article/details/113575557
今日推荐