第十届蓝桥杯(省赛c++)

真题训练

目录

1.(5分)

2.(5分) 

3.

4.(10分)

5.(15分)

6.(15分)

7.(15分)

8.(20分)

9.(25分)



1.(5分)

问题描述

  小明对数位中含有 2、0、1、9 的数字很感兴趣(不包括前导 0),在 1 到
  40 中这样的数包括 1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574。请问,在 1 到 n 中,所有这样的数的和是多少?

输入格式

  输入一行包含两个整数 n。

输出格式

  输出一行,包含一个整数,表示满足条件的数的和。

样例输入

40

样例输出

574

评测用例规模与约定

  对于 20% 的评测用例,1 ≤ n ≤ 10。 对于 50% 的评测用例,1 ≤ n ≤ 100。对于 80% 的评测用例,1 ≤ n ≤ 1000。对于所有评测用例,1 ≤ n ≤ 10000。

在省赛是一个填空题,就是1到2019的平方和,存储这个平方和必须用long,不然int存储不了

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

bool judge(int n){
	int t=n;
	while(t>0){
		int x=t%10;
		if(x==2||x==0||x==1||x==9)
			return true;
		t=t/10;
	}
	return false;
}


int main() {
	long long sum=0;
	for(int i=1;i<=2019;i++){
		if(judge(i)){
			sum+=i*i;
		}
	}
	std::cout<<sum;
	return 0;
}


2.(5分) 

 

这道题我看网上很多题解都是跑不了的,利用斐波那契迭代版可以快速解出,O(1)空间,O(n)时间

#include <stdio.h>
int main(){
  long int num1=1,num2=1,num3=1,num4=0;
  long long i=3;
  while(i<20190324){
	  num4=(num1+num2+num3)%10000;
	  num1=num2;
	  num2=num3;
	  num3=num4;
	  i++;
  }
   printf("%ld",num4);
  return 0;
}

3.

这题关键在于很多人做题会错误地用各种方法,或者是贪心的思想:(49+48+47+46+45+44+43),但是这种做法是错误的,因为求的是中位数,如果第二周的48是那一周的能量(中位数),那么就没有存在三张法术符大于48,所以

这道题不用编程就可以解决,

第一周:X X X 46 47 48 49(X代表只要比后四个数任意小就可以)

第二周:X X X 42 43 44 45

第三周:X X X 38 39 40 41

.....................

以此类推,很快就能得到(46+42+38+34+30+26+22)=238


4.(10分)

 直接暴力,但是可以回溯法(BFS)

下面的文章有完整解析

(2条消息) C++算法——BFS(图解)_隰有游龙的博客-CSDN博客_c++bfs

下面是大佬的代码

 (2条消息) 第十届蓝桥杯 ——迷宫_业余算法学徒的博客-CSDN博客

#include <iostream>
#include <cstring>
#include <queue>
using namespace std;

typedef pair<int, int> PII;

char g[30][50];
int dist[30][50];

char dir[] = {'D', 'L', 'R', 'U'};
int dx[] = {1, 0, 0, -1}, dy[] = {0, -1, 1, 0};

void bfs()
{
	memset(dist, -1, sizeof dist);
	queue<PII> q;
	q.push({29, 49});
	dist[29][49] = 0;
	
	while(q.size())
	{
		PII t = q.front();
		q.pop();
		
		for (int i = 0; i < 4; i ++)
		{
			int a = t.first + dx[i], b = t.second + dy[i];
			if(a < 0 || a >= 30 || b < 0 || b >= 50) continue;
			if(g[a][b] == '1' || dist[a][b] != -1) continue;
			q.push({a, b});
			dist[a][b] = dist[t.first][t.second] + 1;
		}
	}
}

int main()
{
	for (int i = 0; i < 30; i ++) cin >> g[i];
	
	bfs();
	
	string ans;
	int x = 0, y = 0;
	while(x != 29 || y != 49)
	{
		for (int i = 0; i < 4; i ++)
		{
			int a = x + dx[i], b = y + dy[i];
			if(a < 0 || a >= 30 || b < 0 || b >= 50) continue;
			if(g[a][b] == '1') continue;
			if(dist[x][y] == dist[a][b] + 1)
			{
				ans += dir[i];
				x = a, y = b;
				break;
			}
		}
	}

	cout << ans << endl;
	return 0;
}

5.(15分)

数学知识,做不出来。(2条消息) 蓝桥杯 RSA解密_林十六要努力的博客-CSDN博客_蓝桥杯rsa解密


6.(15分)

完全二叉树(注意是完全二叉树而不是满二叉树,我第一次做就入坑,)

没明白为什么只过一个点。。 

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
int a[100002];
int x1[10000]={0};
int main(){
	int n;
	bool flag=0;
	cin>>n;
	int c=n/2;
	if(n<(pow(2,c)-1)){
		flag=1;
		c=c-1;
	}
	int x=0;
	int y;
	for(int i=0;i<n;i++){
		cin>>y;
		a[i]=y;
	}
	x1[0]=a[0];
	for(int i=0;i<c;i++){
		int t=i*2;
		for(int j=x+1;j<=x+t;j++){
			x1[i]+=a[j];
		}
		x+=t;
	}
	if(flag){
		for(int j=(pow(2,c)-1);j<n;j++)
		x1[c]+=a[j];
	}
	int max=-10000000;
	int maxindex=0;
  	for(int i=0;i<c+1;i++){
	  	if(x1[i]>max){
		 	max=x1[i];
			maxindex=i+1; 	
	  	}  
	}
  	cout<<maxindex;
  	return 0;
}

 标准代码:

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+10;
int a[maxn];
long long  b[maxn];
int main()
{
   int n,i,k,j,flag;
   long long ans,x;
   ans=0;
   k=1;
   j=1;
   x= -100000000000;
   flag=0;
   cin>>n;
   for(i=1;i<=n;i++)
   {
       cin>>a[i];
       ans+=a[i];
       if(i==(pow(2,k)-1))
       {
           if(ans>x)
           {
               x=ans;
               j=k;
           }
           ans=0;
           k++;
           flag=1;
       }
       flag=0;
   }
   if(flag==0&&(ans>x))  //当不是完全平衡二叉树的时候
   {
       j=k;
   }
   cout<<j<<endl;
   return 0;
}

7.(15分)

 

就模拟

我用pair+sort()超时,留个心眼吧

总结pair数组用法

typedef pair<int,int> P;
pair<int,int> timex[1000001];
bool cmp(P &s,P &b){
	return s.first<b.first;
}
for(int i=1;i<=1000000;i++){
		cin>>t>>x;
		timex[i]=make_pair(t,x);
}
sort(timex,timex+M,cmp);
cout<<timex[i].first;
cout<<timex[i].second;

 vector删除用法(找出vector小于3的删除)

for(int i=0;i<v.size();i++){
    if(level[v[i]]<3){
        for(vector<int>::iterator a=v.begin();a!=v.end();a++)
        {
            if(*a==v[i]) 
                v.erase(a);
        }
    }
}

上面废话一堆

答案如下

#include <iostream>
#include <algorithm>
using namespace std;

//顺带复习一下结构体的排序hhh
int m,n,t;
//store[id]第id号店上一次有的订单
//flag[id]存储第id号店在不在优先缓存中
//value[id]存储第id号店的得分

int store[100010],flag[100010],value[100010];

struct node{
    int time,id;
}a[100010];

bool cmp(node a , node b){
    if(a.id==b.id)
        return a.time<b.time;
    return a.id<b.id;
}

int main(){
    cin>>n>>m>>t;
    for(int i=0;i<m;i++){
        cin>>a[i].time>>a[i].id;
    }
    sort(a,a+m,cmp);
    for(int i=0;i<m;i++){
        int tt=a[i].time,id=a[i].id;
        //如果当前的订单不等于上一次的订单,则减去它们之间的间隔
        //因为如果没有订单,则每个时刻减1
        if(tt!=store[id])
            value[id]-=tt-store[id]-1;
        //value的值要大于等于0
        value[id]=max(0,value[id]);
        if(value[id]<=3)
            flag[id]=0;
        value[id]+=2;
        if(value[id]>5)
            flag[id]=1;
        store[id]=tt;
    }
    for(int i=1;i<=n;i++){
    //如果这个店的最后一个订单不是第 t 分钟的
    //就减去最后一个订单的时间到 t 时间之间应该减去的
        if(store[i]<t){
            value[i]-=t-store[i];
            if(value[i]<=3)
                flag[i]=0;
        }
    }
    int ans=0;
    for(int i=0;i<=n;i++)
        if(flag[i])
            ans++;
    cout<<ans;
    return 0;
}

8.(20分)

我的代码TLE了,只能捞部分分

注意vector的find是基于algorithm头文件实现的,我这种实现肯定很慢,用dp应该会很快

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
vector<int> s;
int main(){
	int N,t;
	cin>>N;
	cin>>t;
	s.push_back(t);
	for(int i=0;i<N-1;i++){
		cin>>t;
		while(1){
			vector<int>::iterator it=find(s.begin(),s.end(),t);
			if(it!=s.end()){
				t++;
			}	
			else{
				s.push_back(t);
				break;
			}
		}
	}
	for(int i=0;i<s.size();i++)
		cout<<s[i]<<" ";
  	return 0;
}

 

AC(是大佬的并查集)

(2条消息) 蓝桥杯 修改数组 【并查集】_可惜剑是断的的博客-CSDN博客_蓝桥杯修改数组


9.(25分)

状态压缩dp

(2条消息) 2019蓝桥杯C++A组——糖果_芷汀若静的博客-CSDN博客_蓝桥杯糖果

十进制转二进制

看不懂状态压缩可以看这个教程

(2条消息) DP-状态压缩DP(解释+典例)_豆苗子的博客-CSDN博客_状态压缩dp


10.(25分)

难,题目都看不懂,可以自行百度搜索 


  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值