补题,顺便想吐槽一下,这真的是小白入门训练赛?体验真不好。可能太菜了=~=
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=k
,a=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;
}