第十二届蓝桥杯一月校内模拟赛题解

引言

本蒟蒻实力有限,可能有些代码是错误,希望多多包涵,欢迎指出。喜欢本篇文章请一键三连,谢谢~

填空题

请问在 1 到 2020 中,有多少个数既是 4 的整数倍,又是 6 的整数倍
#include <iostream>
using namespace std;
int main()
{
    int ans = 0;
    for(int i = 1; i <= 2020; ++i)
        if(i%4 == 0 && i %6 == 0) ans++;
    cout<<ans<<endl;
    return 0;
}

My Answer:

168
小明要用二进制来表示 1 到 10000 的所有整数,要求不同的整数用不同的
二进制数表示,请问,为了表示 1 到 10000 的所有整数,至少需要多少个
二进制位?
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
using namespace std;
int main()
{
    int temp = 0;
    string s;
    int ans = 0;
    for(int i = 1; i <= 10000; i++)
    {
        s.clear();
        int t = i;
        while(t>0)
        {
            int yu = t%2;
            t /= 2;
            s = s + (char)(yu + '0');
        }
        //cout<<s.size()<<endl;
        ans += s.size();
        int x = s.size();
        temp = max(temp,x);
    }
    cout<<temp<<endl;
    cout<<ans<<endl;
    return 0;
}

My Answer:

14
请问有多少个序列满足下面的条件:
1. 序列的长度为 5。
2. 序列中的每个数都是 1 到 10 之间的整数。
3. 序列中后面的数大于等于前面的数。
#include <iostream>
#include <cstring>
using namespace std;
int a[6];
int main()
{
    int ans = 0;
    for(int i = 10000; i <= 99999; ++i)
    {
        memset(a, 0, sizeof a);
        int t = i, idx = 0;
        while(t>0)
        {
            a[idx++] = t%10;
            t /= 10;
        }
        int ok = 1;
        for(int j = 0; j < idx-1; j++)
            if(a[j] < a[j+1] || a[j] <= 1) ok = 0;
        if(ok) ans++;
    }
    cout<<ans<<endl;
    return 0;
}

My Answer:

1122
一个无向图包含 2020 条边,如果图中没有自环和重边,请问最少包含多
少个结点?

My Answer:

2021
两个字母之间的距离定义为它们在字母表中位置的距离。例如 A 和 C 的
距离为2,L 和 Q 的距离为 5。对于一个字符串,我们称字符串中两两字
符之间的距离之和为字符串的内部距离。例如:ZOO 的内部距离为 22,其
中 Z 和 O 的距离为 11。请问,LANQIAO 的内部距离是多少?
#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main()
{
    int ans = 0;
    string s = "LANQIAO";
    for(int i = 0; i < s.size(); i++)
        for(int j = i + 1; j < s.size(); j++)
        {
         //   if(s[j] > s[i]) cout<<s[j]<<" - " <<s[i]<< " = "<<s[j]-s[i]<<endl;
          //  else cout<<s[i]<<" - " <<s[j]<< " = "<<s[i]-s[j ]<<endl;
            if(s[j] < s[i]) ans = ans + (int)(s[i] - s[j]);
            else  ans = ans + (int)(s[j] - s[i]);
        }
    cout<<ans<<endl;
    return 0;
}

My Answer:

162

编程题

题目描述
给定一个平行四边形的底边长度 l l l 和高度 h h h,求平行四边形的面积。
输入格式
输入的第一行包含一个整数 l l l,表示平行四边形的底边长度。
第二行包含一个整数 h h h,表示平行四边形的高。
输出格式
输出一个整数,表示平行四边形的面积。(提示:底边长度和高都是整数的平行四边形面积为整数)
样例输入

2
7

样例输出

14

数据规模和约定
对于所有评测用例: 1 ≤ l , h ≤ 100 1 \leq l, h \leq 100 1l,h100

#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main()
{
    int l,h;
    cin>>l>>h;
    int ans = l*h;
    cout<<ans<<endl;
    return 0;
}

题目描述
现在时间是 a a a b b b 分,请问 t t t 分钟后,是几点几分?
输入格式
输入的第一行包含一个整数 a a a
第二行包含一个整数 b b b
第三行包含一个整数 t t t
输出格式
输出第一行包含一个整数,表示结果是几点。
第二行包含一个整数,表示结果是几分。
样例输入

3
20
165

样例说明

6
5

数据规模和约定
对于所有评测用例: 0 ≤ a ≤ 23 , 0 ≤ b ≤ 59 , 0 ≤ t , t 0 \leq a \leq 23, 0 \leq b \leq 59, 0 \leq t, t 0a23,0b59,0t,t 分钟后还是在当天。

#include <iostream>
#include <cstring>
#include <string>
using namespace std;
int main()
{
    int a,b,t;
    cin>>a>>b>>t;
    int yu = (b+t)%60;
    int s = (b+t)/60;
    cout<<(a+s)<<endl;
    cout<<yu<<endl;
    return 0;
}

题目描述
小蓝负责花园的灌溉工作。
花园可以看成一个 n n n m m m 列的方格图形。中间有一部分位置上安装有出水管。
小蓝可以控制一个按钮同时打开所有的出水管,打开时,有出水管的位置可以被认为已经灌溉好。
每经过一分钟,水就会向四面扩展一个方格,被扩展到的方格可以被认为已经灌溉好。即如果前一分钟某一个方格被灌溉好,则下一分钟它上下左右的四个方格也被灌溉好。
给定花园水管的位置,请问 k k k 分钟后,有多少个方格被灌溉好?
输入格式
输入的第一行包含两个整数 n n n, m m m
第二行包含一个整数 t t t,表示出水管的数量。
接下来 t t t 行描述出水管的位置,其中第 i i i 行包含两个数 r , c r, c r,c 表示第 r r r 行第 c c c 列有一个排水管。
接下来一行包含一个整数 k k k
输出格式
输出一个整数,表示答案。
样例输入

3 6
2
2 2
3 4
1

样例输出

9

样例说明
用1表示灌溉到,0表示未灌溉到。
打开水管时:
  000000
  010000
  000100
1分钟后:
  010000
  111100
  011110
  共有9个方格被灌溉好。
数据规模和约定  
对于所有评测用例: 1 ≤ n , m ≤ 100 , 1 ≤ t ≤ 10 , 1 ≤ k ≤ 100 1 \leq n, m \leq 100, 1 \leq t \leq 10, 1 \leq k \leq 100 1n,m100,1t10,1k100
将最初水龙头的位置标记,存入队列,再用一个队列存储下一分钟蔓延的位置,每分钟结束,更新队列中的元素,最后输出在规定时间内灌溉的位置有多少个即可。

#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;
char mp[110][110];
int vis[110][110];
int dir[4][2] = {0,1,-1,0,0,-1,1,0};
struct node{
    int x,y;
    char ch;
};
node a[110];
bool inbound(int x, int l, int r)
{
    if(x < l || x > r) return false;
    return true;
}

int main()
{
    int n,m,t;
    cin>>n>>m>>t;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++) vis[i][j] = 0, mp[i][j] = '0';
    queue<node> q;
    for(int i = 0; i < t; i++)
    {
        int x,y;
        cin>>x>>y;
        mp[x][y] = '1';
        vis[x][y] = 1;
        a[i] = {x,y,'1'};
        q.push(a[i]);
    }
    int ans = t, k = 0;
    cin>>k;
    int time = 0;
    queue<node> p;
    while(!q.empty())
    {
        node now = q.front();
        q.pop();
        int x = now.x, y = now.y;
        char ch = now.ch;
        for(int i = 0; i < 4; i++)
        {
            int tx = x + dir[i][0];
            int ty = y + dir[i][1];
            if(!inbound(tx,1,n) || !inbound(ty,1,m)) continue;
            if(!vis[tx][ty] && mp[tx][ty] == '0')
            {
                ans++;
                node temp = {tx,ty,'1'};
                mp[tx][ty] = '1';
                p.push(temp);
            }
        }
        if(q.empty())
        {
            time++;
            while(!p.empty())
            {
                node s = p.front();
                p.pop();
                q.push(s);
            }
        }
        if(time >= k) break;
    }
    cout<<ans<<endl;
    /***
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            cout<<mp[i][j]<<" ";
        }
        cout<<'\n';
    }
    ***/
    return 0;
}

题目描述
小蓝有一张黑白图像,由 n ∗ m n * m nm 个像素组成,其中从上到下共 n n n 行,每行从左到右 m m m 列。每个像素由一个 0 到 255 之间的灰度值表示。
现在,小蓝准备对图像进行模糊操作,操作的方法为:
对于每个像素,将以它为中心 3 * 3 区域内的所有像素(可能是 9 个像素或少于 9 个像素)求和后除以这个范围内的像素个数(取下整),得到的值就是模糊后的结果。
请注意每个像素都要用原图中的灰度值计算求和。
输入格式
输入的第一行包含两个整数 n , m n, m n,m
第 2 行到第 n + 1 n + 1 n+1 行每行包含 m m m 个整数,表示每个像素的灰度值,相邻整数之间用一个空格分隔。
输出格式
输出 n n n 行,每行 m m m 个整数,相邻整数之间用空格分隔,表示模糊后的图像。
样例输入

3 4
0 0 0 255
0 0 255 0
0 30 255 255

样例输出

0 42 85 127
5 60 116 170
7 90 132 191

数据规模和约定
对于所有评测用例, 1 ≤ n , m ≤ 100 1 \leq n, m \leq 100 1n,m100
扩展有8个方向扩展,然后以当前这个点为中心向 8 个方向扩展即可,最后按照题意求模糊值。

#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;
int vis[110][110];
int dir[8][2] = {0,1,-1,1,-1,0,-1,-1,0,-1,1,-1,1,0,1,1};
int mp[110][110];
int ans[110][110];
bool inbound(int x, int l, int r)
{
    if(x < l || x > r) return false;
    return true;
}

int main()
{
    int n,m;
    cin>>n>>m;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++) cin>>mp[i][j];

    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            int t = mp[i][j], cnt = 1;
            for(int k = 0; k < 8; k++)
            {
                int tx = i + dir[k][0];
                int ty = j + dir[k][1];
                if(!inbound(tx,1,n) || !inbound(ty,1,m)) continue;
                t += mp[tx][ty];
                cnt++;
            }
            ans[i][j] = (int)(t/cnt);
        }
    }
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
            if(j == 1) cout<<ans[i][j];
            else cout<<" "<<ans[i][j];
        cout<<'\n';
    }

    return 0;
}

题目描述
小蓝在一个 n n n m m m 列的方格图中玩一个游戏。
开始时,小蓝站在方格图的左上角,即第 1 行第 1 列。
小蓝可以在方格图上走动,走动时,如果当前在第 r r r 行第 c c c 列,他不能走到行号比 r r r 小的行,也不能走到列号比 c c c 小的列。同时,他一步走的直线距离不超过3。
例如,如果当前小蓝在第 3 行第 5 列,他下一步可以走到第 3 行第 6 列、第 3 行第 7 列、第 3 行第 8 列、第 4 行第 5 列、第 4 行第 6 列、第 4 行第 7 列、第 5 行第 5 列、第 5 行第 6 列、第 6 行第 5 列之一。
小蓝最终要走到第 n n n 行第 m m m 列。
在图中,有的位置有奖励,走上去即可获得,有的位置有惩罚,走上去就要接受惩罚。奖励和惩罚最终抽象成一个权值,奖励为正,惩罚为负。
小蓝希望,从第 1 行第 1 列走到第 n n n 行第 m m m 列后,总的权值和最大。请问最大是多少?
输入格式
输入的第一行包含两个整数 n , m n, m n,m,表示图的大小。
接下来 n n n 行,每行 m m m 个整数,表示方格图中每个点的权值。
输出格式
输出一个整数,表示最大权值和。
样例输入

3 5
-4 -5 -10 -3 1
7 5 -9 3 -10
10 -2 6 -10 -4

样例输出

15

数据规模和约定
对于30%的评测用例, 1 ≤ n , m ≤ 10 1 \leq n, m \leq 10 1n,m10
对于50%的评测用例, 1 ≤ n , m ≤ 20 1 \leq n, m \leq 20 1n,m20
对于所有评测用例, 1 ≤ n ≤ 100 , − 10000 ≤ 权 值 ≤ 10000 1 \leq n \leq 100,-10000 \leq 权值 \leq 10000 1n1001000010000

动态规划, d p [ i ] [ j ] dp[i][j] dp[i][j] 表示在第 i i i j j j 列,属性表示权值,处理特殊的行和列以及特殊的点,然后其余点的状态转移方程就是在可以扩展来的点选取最大值加。答案就是 d p [ n ] [ m ] dp[n][m] dp[n][m]

#include <iostream>
#include <cstring>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;
int vis[110][110];
int mp[110][110];
int ans[110][110];

int main()
{
    int n,m;
    memset(mp, 0, sizeof mp);
    memset(ans,0,sizeof ans);
    cin>>n>>m;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= m; j++) cin>>mp[i][j],ans[i][j] = mp[i][j];

    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            if(i == 1)
            {
                if(j == 1) continue;
                else if(j == 2) ans[i][j] += mp[i][j-1];
                else if(j == 3) ans[i][j] += max(mp[i][j-2],ans[i][j-1]);
                else ans[i][j] +=  max(ans[i][j-1],max(ans[i][j-2],mp[i][j-3]));
            }
            else if(j == 1)
            {
                if(i == 2) ans[i][j] += mp[i-1][j];
                else if(i == 3) ans[i][j] += max(ans[i-1][j],mp[i-2][j]);
                else ans[i][j] += max(ans[i-1][j],max(ans[i-2][j],mp[i-3][j]));
            }
            else if(i == 2 && j == 2)
            {
                ans[i][j] += max(mp[1][1],max(mp[1][2],mp[2][1]));
            }
            else if(i == 2 && j == 3)
            {
                int x = max(mp[1][1],mp[1][2]);
                int y = max(mp[2][1],mp[2][2]);
                ans[i][j] += max(mp[1][3],max(x,y));
            }
            else if(i == 3 && j == 2)
            {
                int x = max(mp[1][1],mp[1][2]);
                int y = max(mp[2][1],mp[2][2]);
                ans[i][j] += max(mp[3][1],max(x,y));
            }
            else
            {
                int x = max(ans[i][j-1],max(ans[i][j-2],ans[i][j-3]));
                int y = max(ans[i-1][j],max(ans[i-2][j],ans[i-3][j]));
                int z = max(ans[i-1][j-1],max(ans[i-2][j-1],ans[i-1][j-2]));
                ans[i][j] += max(x,max(y,z));
            }
        }
    }

    /***
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= m; j++)
        {
            cout<<ans[i][j]<<" ";
        }
        cout<<'\n';
    }
    ***/
    cout<<ans[n][m]<<endl;
    return 0;
}

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幸愉信奥

谢谢亲的支持,我会继续努力啦~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值