2021牛客寒假算法基础集训营1 -1
A
长度不超过nn,且包含子序列“us”的、只由小写字母构成的字符串有多少个? 答案对10^9+7取模。
所谓子序列,指一个字符串删除部分字符(也可以不删)得到的字符串。
例如,“unoacscc"包含子序列"us”,但"scscucu"则不包含子序列"us".
f[i]表示长度为i的有us的串的数量
• 1.之前已经有完整的us ,所以第i个位置随便添加
• f[i] += f[i-1] * 26
• 2.之前没有us,但是有一个或者多个u,当前位置必须加一个s • 先算之前有u但是u后面没有s的串的数量:
• 总数-没有u的-有us的 • 26^(i-1) – 25^(i-1) – f[i-1]
• f[i] += (26^(i-1) – 25^(i-1) – f[i-1])*1
• 综上:f[i] = 26^(i-1) – 25^(i-1) + 25f[i-1]
#include <iostream>
using namespace std;
#define maxn 2000100
int mod=1e9+7;
typedef long long ll;
ll f[maxn],n,res;
ll power(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
int main()
{
cin>>n;
f[2]=1;
if(n==2)
{
cout<<"1";
}
else
{
for(int i=3;i<=n;i++) f[i]=(f[i-1]*25+power(26,i-1)-power(25,i-1)+mod)%mod;
for(int i=2;i<=n;i++) res=(res+f[i])%mod;
cout<<res;
}
return 0;
}
B
请
你构造一个非空的括号字符串,包含正好 kk 个不同合法括号对。
所谓括号字符串,是指由’(‘和’)'这两种字符构成的字符串。
要求构造的字符串长度不超过 100000。
输入描述:
一个整数 k。
0≤k≤1e9
输出描述:
一个仅包含左右括号字符串,其中有 k 个合法的括号对。如果有多种构造方法,输出任意一种合法方案即可。
在((( ))))中有3*4=12 个括号,((( )))() 在最后一个括号前添加n新的左括号就可以多n个合法括号对。
因为0<=k<=1e9
所以”(“ 的个数可以为sqrt(k)个,“)” 的个数是k/sqrt(k)个,最后填上剩下的“(”。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll mm,n,m,r,k;
int main()
{
cin>>n;
if (n==0) {printf(")(");return 0;}
m=sqrt(n);
mm=n/m;
r=n-(mm*m);
for (int i=1;i<=m;i++) printf("(");
for (int i=1;i<mm;i++) printf(")");
for (int i=1;i<=r;i++) printf("(");
printf(")");
}
F。
考试结束了,牛牛和牛妹开始对答案。
每道题有 ABCD 四个选项,一共有道题,全部是单选题,每道题正确得 1 分,错误不得分。
牛牛和牛妹互相知道了他们每道题选择的选项。他们想知道,两个人得分之和有可能达到的最大值和最小值是多少?
min恒=0;
max=n+相同的选项;
#include<bits/stdc++.h>
using namespace std;
char ch;
int a[200],b[200],ans,n;
int main()
{
cin>>n;
for (int i=1;i<=n;i++) cin>>ch,a[i]=ch-'A';
for (int i=1;i<=n;i++) cin>>ch,b[i]=ch-'A';
for (int i=1;i<=n;i++) if (a[i]==b[i]) ans++;
ans+=n;
cout<<ans<<" "<<0<<endl;
}
I
题目描述
输入一个数n,请构造一个长度为n的排列,使得其中正好有k对相邻的数gcd(最大公约数)大于1 。
排列是指 1到n一共n个数,每个数都出现过且仅出现过1次。
输出描述:
如果不存在可行的构造方案,输出-1。
否则输出一行 个数,用空格隔开。如果有多组可行的构造方案,输出任意一组即可。
n=9
k=1 {6,3,1,2,4,5,7,8,9}
k=2 {2,6,3,1,4,5,7,8,9}
k=3 {2,4,6,3,1,5,7,8,9}
k=4 {2,4,8,6,3,1,5,7,9}
#include<bits/stdc++.h>
using namespace std;
int m,n,k,i,f[100006];
int main()
{
cin>>n>>k;
if (k==0)
{
for (int i=1;i<=n;i++) cout<<i<<" ";
}
else
{
if (n<=3)
{
cout<<-1;
return 0;
}
if (n==4)
{
if (k==1)
{
cout<<"2 4 1 3";
return 0;
}
if (k==2)
{
cout<<-1;
return 0;
}
}
if (n==5)
{
if (k==1)
{
cout<<"2 4 1 3 5";
return 0;
}
if (k==2)
{
cout<<-1;
return 0;
}
}
for (int m=1;m<=k-1;m++)
{
i++;
if (i==3) i++;
cout<<i*2<<" ";
f[i*2]=1;
}
cout<<"6 3 ";
f[6]=f[3]=1;
for (int i=1;i<=n;i++) if (!f[i]) cout<<i<<" ";
}
}
J
用数学语言描述,第 只青蛙的路线是首项为1,公比为的等比数列,其中代表第个素数。
当青蛙跳到一个格子上,如果这个格子上面有一个数,青蛙就会把这个数吃掉。
牛牛想知道,所有没有被吃掉的数的lcm(最小公倍数 ,Least common multiple)是多少?
由于这个lcm可能非常大,请输出它对取模的值。
n=19
6=2 * 3
10=2 * 5
12=2 * 2 * 3
14=2 * 2 * 7
18=2 * 3 * 3
lcm(6,10,12,14,18)=2 * 2 * 3 * 3 * 5 * 7
……
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int cnt;
int prime[10000000];
bool st[1000000000];
void get_prime(int n){
for(int i=2;i<n;i++){
if(!st[i])prime[cnt++]=i;
for(int j=0;prime[j]<=n/i;j++){
st[i*prime[j]]=true;
if(i%prime[j]==0)break;
}
}
}
int main(){
int n;
cin>>n;
get_prime(n);
ll res=1,mod=1e9+7;
if(n<6){
cout<<"empty";
return 0;
}
for(int i=1;prime[i]<=n/2;i++){
ll p=prime[i],temp=1;
while(temp*p<=n/2)temp*=p;
res=res*temp%mod;
}
ll temp2=1;
while(temp2*2<=n/3)temp2*=2;
res=res*temp2%mod;
cout<<res;
}