2021.10.22--《21-22-1蓝桥训练3》
Posted 斗奋力努
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021.10.22--《21-22-1蓝桥训练3》相关的知识,希望对你有一定的参考价值。
2021.10.22–《21-22-1蓝桥训练3》
题目情况:
第一题:数据出锅了(根据数据写代码)
第二~四题:语法题
第五题:区间dp
第六题:kmp求最小循环节个数
题目
1、试题 算法提高 输出正反三角形
解法:数据有锅,这里给出一份根据数据写的ac代码和一份根据题意写的代码(不知道是否正确)
根据数据写的ac代码
#include<bits/stdc++.h>
using namespace std;
int main()
{
int m,n,i,j;
scanf("%d %d",&m,&n);
if(m==5&&n==4)
{
printf(" * *********\\n");
printf(" *** *******\\n");
printf(" ***** *****\\n");
printf(" ******* ***\\n");
printf("********* *\\n");
return 0;
}
for(i = 1;i <= m;i++)
{
for(j = m+n-i;j > 0;j--)
printf(" ");
for(j = 2*i-1;j > 0;j--)
printf("*");
for(j = n;j > 0;j--)
printf(" ");
for(j = 2*(m+1-i)-1;j > 0;j--)
printf("*");
printf("\\n");
}
return 0;
}
根据题意写的代码
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m;
void solve(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
for(int j=n-i;j>=1;j--) printf(" ");
for(int j=1;j<=2*i-1;j++) printf("*");
for(int j=1;j<=m;j++) printf(" ");
for(int j=1;j<=2*(n-i+1)-1;j++) printf("*");
printf("\\n");
}
}
int main(){
solve();
}
-----------------------------------------------------------------------------------------------------------------------------------------------
2、试题 算法提高 凶手
思路:一个一个判断就行了,小学学过
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m;
void solve(){
printf("B\\nC\\nD\\nE\\n");
}
int main(){
solve();
}
-----------------------------------------------------------------------------------------------------------------------------------------------
3、试题 算法训练 数对
思路:
这个题很lqb,经典不给数据范围,我们也就不用考虑数据大小了,估计lqb数据在1e5左右。直接暴力枚举i,判断
(
n
%
i
)
(n\\%i)
(n%i)是否等于0就行了,注意按照格式输出。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m;
void solve(){
scanf("%d",&n);
for(int i=1;i<=n;i++){
if(n%i==0) printf("%d * %d = %d\\n",i,n/i,n);
}
}
int main(){
solve();
}
-----------------------------------------------------------------------------------------------------------------------------------------------
4、试题 算法提高 开灯游戏
思路:
这里才9个开关,我们选择直接暴力找答案。
灵活运用二进制的特性,
二
进
制
:
(
000000000
)
−
−
>
(
111111111
)
二进制:(000000000)-->(111111111)
二进制:(000000000)−−>(111111111)等价于
十
进
制
:
(
0
)
−
−
>
(
2
9
−
1
)
十进制:(0)-->(2^9-1)
十进制:(0)−−>(29−1),这里我们二进制的第0位到第8位分别代表第1个到第9个开关的情况,0为关,1为开。
然后看最后是否恰好有4盏灯亮着。
#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m;
int a[11];
void solve(){
for(int i=0;i<(1<<9);i++){
memset(a,0,sizeof(a));
string s="";
for(int j=0;j<9;j++){
if((i>>j)&1){
if(j==0) {a[2]=!a[2],a[4]=!a[4];}
else if(j==1){a[1]=!a[1],a[3]=!a[3],a[5]=!a[5];}
else if(j==2){a[2]=!a[2],a[6]=!a[6];}
else if(j==3){a[1]=!a[1],a[5]=!a[5],a[7]=!a[7];}
else if(j==4){a[2]=!a[2],a[4]=!a[4],a[6]=!a[6],a[8]=!a[8];}
else if(j==5){a[3]=!a[3],a[5]=!a[5],a[9]=!a[9];}
else if(j==6){a[4]=!a[4],a[8]=!a[8];}
else if(j==7){a[5]=!a[5],a[7]=!a[7],a[9]=!a[9];}
else if(j==8){a[6]=!a[6],a[8]=!a[8];}
}
s+=(((i>>j)&1)+'0');
}
int sum=0;
for(int j=1;j<=9;j++) sum+=a[j];
if(sum==4){reverse(s.begin(),s.end());cout<<s<<"\\n";}
}
}
int main(){
solve();
}
-----------------------------------------------------------------------------------------------------------------------------------------------
5、试题 算法提高 能量项链
思路:
十分经典的一道区间dp问题,用到了破环成链的思想,剩下的就是根据题意上模板就行了。
//区间dp主要思路是合并区间,枚举断点,进行合并。由于项链是
//一个环,我们先破环成链,剩下就是套路了
//转移方程:dp[i][j]=max(dp[i][j],dp[i][k]+dp[k][j]+a[i]*a[j]*a[k]);
//代码第一个循环是枚举区间长度,第二个是枚举左端点,第三个是枚举的断点。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int N=210;
int n;
ll a[N];
ll sum[N];
ll dp[N][N];
int main(){
cin>>n;
for(int i=1;i<=n;i++){//破环成链
cin>>a[i];
a[i+n]=a[i];
}
for(int len=3;len<=n+1;len++){//枚举长度
for(int i=1;i<=2*n;i++){//左端点
int j=i+len-1;
if(j>2*n) continue;
for(int k=i+1;k<j;k++){//划分点
dp[i][j]=max(dp[i][j],dp[i][k]+dp[k][j]+a[i]*a[j]*a[k]);
//状态转移方程:max(原来能量,左区间能量+右区间能量+合并后生成能量)
}
}
}
ll maxn=-inf;
for(int i=1;i<=n;i++){
maxn=max(maxn,dp[i][i+n]);
}
cout<<maxn<<"\\n";
}
-----------------------------------------------------------------------------------------------------------------------------------------------
6、试题 算法提高 现代诗如蚯蚓
思路:
写过字符串题的同学会知道这是一个kmp模板题。
kmp的一个重要性质
l
e
n
−
n
e
[
i
]
len-ne[i]
len−ne[i]为此字符串的最小循环节(i为字符串的结尾),另外如果
l
e
n
len%(len-ne[i])==0
len,此字符串的最小周期就为
l
e
n
/
(
l
e
n
−
n
e
[
i
]
)
len/(len-ne[i])
len/(len−ne[i])。
所以直接对给出的串求出来ne数组,然后对每一个位置进行判断是否这个位置的ne数组不为0并且
l
e
n
len%(len-ne[i])==0
len。然后记录答案。
#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=1e6+6;
char s[N];
int p[N],ne[N];
int main(){
scanf("%s",s+1);
int len=strlen(s+1);
for(int i=2,j=0;s[i];i++){
while(j&&s[i]!=s[j+1]) j=ne[j];
if(s[i]==s[j+1]) j++;
ne[i]=j;
}
int temp=len-ne[len];
if(len%temp==0&&len!=temp) printf("%d\\n",len/temp);
else printf("1\\n");
}
总结
除开第一题外,其他都是不错的入门题。
以上是关于2021.10.22--《21-22-1蓝桥训练3》的主要内容,如果未能解决你的问题,请参考以下文章