第十五(15)届蓝桥杯模拟赛题解+AC代码(第二期)

纵有千古,横有八荒,前途似海,来日方长----梁启超

My friends,觉得写的不错,记得点赞,关注,收藏!!!

题目1:

7cf712bc9cc4433aa95782eda1e263e8.png

思路:

1.先算出一行总的像素30*36,之后改为每个字宽10个像素,用一行总的像素/10,30*36/10,等于多少呢?

答案:108

题目2:

c53d9cd2f95a4605bfb1e9d974f76c9c.png

思路:

1.一个for循环,枚举2023次即可

2.假若枚举次数过多,可以用快速幂优化,不过这里是填空,不考虑时间复杂度

AC_Code:C++

#include<bits/stdc++.h>

using namespace std;

int main()
{
    int ans=1;
    for(int i=0;i<2023;i++)	ans=ans*2%1000;
    cout<<ans;
	
	return 0;
}

答案:608

题目3:

dea50d23a717436bbe818600f97f967e.png

思路:

1.从1开始枚举,对每个数转化为二进制与八进制,看数位相加是否相等,相等个数++

2.直到第23个数转化为二进制与八进制数位相等,输出答案结束程序

3.十进制转其他进制数时,边除边取余数即可

AC_Code:C++

#include <iostream>
#include<bits/stdc++.h>

using namespace std;

//转化为二进制,统计数位
int get2(int n){
	int res=0;
	while(n)	res+=n%2,n/=2;
	return res;
}

//转化为八进制,统计数位
int get8(int n){
	int res=0;
	while(n)	res+=n%8,n/=8;
	return res;
}

int main()
{
    int cnt=0;	//记录第几个数,二八进制数位和相等
    for(int i=1;;i++){
	 	if(get2(i)==get8(i)){
			cnt++;
			if(cnt==23){
				cout<<i<<endl;
				return 0;
			}
		}
	}
	
	return 0;
}

答案:4169

题目4:

3fed182c4df849b49571faee5c3d4b2c.png

input:

393353 901440 123481 850930 423154 240461
373746 232926 396677 486579 744860 468782
941389 777714 992588 343292 385198 876426
483857 241899 544851 647930 772403 109929
882745 372491 877710 340000 659788 658675
296521 491295 609764 718967 842000 670302

思路:

约数:n%m==0,m则是n的约数

1.统计每个数的约数个数,找出最大值即可

2.求一个数x的约数个数,i从1枚举到x,看有多少个x%i==0,

AC_Code:C++

#include <iostream>

using namespace std;

int n;
int a[47];

int get(int n){
	int cnt=0;
	for(int i=1;i<=n;i++)
		if(n%i==0) cnt++;
		
	//一个小优化,不过填空题还是怎么快怎么来吧,	
//	for(int i=1;i<=n/i;i++)
//		if(n%i==0){
//			cnt++;	
//			if(i!=n/i)	cnt++;
//		}
		
	return cnt;
}

int main()
{
	n=36;
    for(int i=0;i<n;i++)	cin>>a[i];
    
    int mx=-1,idx=-1;	//记录约数个数的最大值,与其对应的下标
    for(int i=0;i<n;i++){
		int cnt=get(a[i]);
		if(cnt>mx){
			mx=cnt;
			idx=i;
		}
	}
	
	cout<<a[idx]<<endl;
	
	return 0;
}

答案:901440

题目5:

0c94595feffc4706a49d3d771af36b39.png

input:

0000100010000001101010101001001100000011
0101111001111101110111100000101010011111
1000010000011101010110000000001011010100
0110101010110000000101100100000101001001
0000011010100000111111001101100010101001
0110000110000000110100000000010010100011
0100110010000110000000100010000101110000
0010011010100110001111001101100110100010
1111000111101000001110010001001011101101
0011110100011000000001101001101110100001
0000000101011000010011111001010011011100
0000100000011001000100101000111011101100
0010110000001000001010100011000010100011
0110110000100011011010011010001101011011
0000100100000001010000101100000000000010
0011001000001000000010011001100101000110
1110101000011000000100011001001100111010
0000100100111000001101001000001010010001
0100010010000110100001100000110111110101
1000001001100010011001111101011001110001
0000000010100101000000111100110010101101
0010110101001100000100000010000010110011
0000011101001001000111011000100111010100
0010001100100000011000101011000000010101
1001111010010110011010101110000000101110
0110011101000010100001000101001001100010
1101000000010010011001000100110010000101
1001100010100010000100000101111111111100
1001011010101100001000000011000110110000
0011000100011000010111101000101110110001

思路:dfs/bfs

1本题的意思其实就是,在第一行第一列等于0的字符,跑一遍dfs/bfs,染色染成2,其实也是联通块的问题,也称洪水灌溉算法。

2.最后统计字符2的个数为多少。

AC_Code:C++

#include <iostream>
#include<queue>

using namespace std;
typedef pair<int,int>PII;
#define x first
#define y second

int const N=57;


int T;
int n=30,m=40;
char s[N][N];
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};

void dfs(int x,int y){
	s[x][y]='2';
	
	for(int i=0;i<4;i++){
		int bx=dx[i]+x,by=dy[i]+y;
		if(bx<1||by<1||bx>n||by>m)	continue;
		if(s[bx][by]=='0')	dfs(bx,by);
	}
}

void bfs(int sx,int sy){
	queue<PII>q;
	q.push({sx,sy});
	s[sx][sy]='2';
	
	while(q.size()){
		PII t=q.front();	q.pop();
		
		for(int i=0;i<4;i++){
			int bx=dx[i]+t.x,by=dy[i]+t.y;
			if(bx<1||by<1||bx>n||by>m)	continue;
			if(s[bx][by]=='0'){
				s[bx][by]='2';
				q.push({bx,by});
			}	
		}
	}
}

int main(){
    for(int i=1;i<=n;i++)	scanf("%s",s[i]+1);
    
    //dfs
    for(int j=1;j<=m;j++) 
		if(s[1][j]=='0') dfs(1,j);
    for(int i=1;i<=n;i++) 
		if(s[i][1]=='0') dfs(i,1);
	
	//bfs
//	for(int j=1;j<=m;j++) 
//		if(s[1][j]=='0') bfs(1,j);
//    for(int i=1;i<=n;i++) 
//		if(s[i][1]=='0') bfs(i,1);
    
    //统计字符2的数量
    int ans=0;
    for(int i=1;i<=n;i++)
    	for(int j=1;j<=m;j++)	
    		ans+=s[i][j]=='2';
    
    cout<<ans<<endl;
    
    return 0;
} 

答案:591

题目6:

f5bac721fa68477eafc56d9c1c263cda.png

思路:

1.最高两位不为0,那么可以直接输出次高位到个位,最后输出最高一位

AC_Code:C++

#include <iostream>

using namespace std;

string s;

int main()
{
    cin>>s;
    for(int i=1;i<6;i++)	cout<<s[i];
    cout<<s[0];
    
	return 0;
}

题目7:

7a838015edb344cda8a87d294d2ae78e.png

思路:

1.统计5个元音字母中最后一次出现的字母,我们可以倒序枚举,那么首次出现的元音字母就答案(题目保证了一定有一个元音字母)

AC_Code:C++

#include <iostream>

using namespace std;

string s;

void solve(){
    cin>>s;
    for(int i=s.size()-1;i>0;i--){
		if(s[i]=='a'){
			cout<<s[i];	return;
		}
		
		if(s[i]=='e'){
			cout<<s[i];	return;
		}
		
		if(s[i]=='i'){
			cout<<s[i];	return;
		}
		
		if(s[i]=='o'){
			cout<<s[i];	return;
		}
		
		if(s[i]=='u'){
			cout<<s[i];	return;
		}

	}
} 

int main()
{
    solve();
	return 0;
}

题目8:

533c6aeac0a7427e887f1c758bc86fc5.png

思路:

1.拆出每一位来,(除0外)相乘即可,直到小于10

2.记得开long long 

AC_Code:C++

#include <iostream>

using namespace std;
typedef long long LL;

int main(){
    LL n;	cin>>n;
    
    if(n<=9){	//特判n<=9的情况
		cout<<n<<endl;
		return 0;
	}
    
    while(n>=10){
		LL temp=n;
		LL next_n=1;
		
		//拆出每一位相乘
		while(temp){
			if(temp%10>0)	next_n*=temp%10;
			temp/=10;
		}
		
		n=next_n;
		printf("%lld\n",n);
	}
	
	return 0;
} 

题目9:

f76f1ef9f6cf4cd2a3e18e73907ab4ee.png

input:

3 4
3 6 5 5
2 4 3 5
7 8 3 8
3 2

output:

5

eb22ae29a13445fbb10ace25d65f0538.png

思路:dfs/bfs

1.联通块问题,不过联通的条件是最大公约数大于1,dfs/bfs都可以行,此算法也称洪水灌溉算法

AC_Code:C++

#include <iostream>
#include <queue>

using namespace std;

typedef long long LL;
typedef pair<int,int>PII;

#define x first
#define y second


int const N=1007;


int T;
int n,m;
int sx,sy;
int a[N][N];
bool vis[N][N];
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};

int gcd(int a,int b){
	return b==0?a:gcd(b,a%b);
}

int dfs(int x,int y){
	vis[x][y]=1;
	
	int res=1;
	for(int i=0;i<4;i++){
		int bx=dx[i]+x,by=dy[i]+y;
		if(bx<1||by<1||bx>n||by>m||vis[bx][by])	continue;
		if(gcd(a[x][y],a[bx][by])==1)	continue;
		res+=dfs(bx,by);
	}
	
	return res;
}

int bfs(int sx,int sy){
	queue<PII>q;	q.push({sx,sy});
	int res=0;
	while(q.size()){
		PII t=q.front();	q.pop();
		res++;
		
		for(int i=0;i<4;i++){
			int bx=dx[i]+t.x,by=dy[i]+t.y;
			if(bx<1||by<1||bx>n||by>m||vis[bx][by])	continue;
			if(gcd(a[t.x][t.y],a[bx][by])==1)	continue;
			q.push({bx,by});
			vis[bx][by]=true;
		}
		
	}
	
	return res;
}


int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    	for(int j=1;j<=m;j++)
    		scanf("%d",&a[i][j]);
    
    scanf("%d%d",&sx,&sy);
    
    vis[sx][sy]=true;
    
    //cout<<dfs(sx,sy);
    cout<<bfs(sx,sy);
    
    return 0;
} 


题目10:

d029a62d78034000ad361dc38daf8abc.png

思路:

1.找出一个长为k的区间和的最大值,区间长度确定,可以直接用滑动窗口,

2.也可以枚举起点,用前缀和o(1)计算区间和

AC_Code:C++

#include <iostream>

using namespace std;

typedef long long LL;

int const N=1e5+7;

int n,k;
int a[N];
LL pre[N];

int main(){
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++){
		scanf("%d",a+i);
		pre[i]=pre[i-1]+a[i];
	}
	
	//前缀和+枚举起点
//	LL ans=-1;
//	for(int i=1;i+k-1<=n;i++)
//		ans=max(ans,pre[i+k-1]-pre[i-1]);
	
	//滑动窗口
	LL sum=0,ans=-1;
	for(int i=1;i<=n;i++){
		sum+=a[i];
		if(i>k)	sum-=a[i-k];
		if(i>=k)	ans=max(ans,sum);
	}
	
	cout<<ans;
	
	return 0;
} 

My friends,觉得写的不错,不要忘记点赞,关注,收藏哦!!!

  • 6
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值