第十二届蓝桥杯大赛模拟赛(第二期,已更新题解)

莫名感觉模拟赛永远比正赛简单亿点点

第一题

问题描述 :

小明要用二进制来表示 1 到 10000 的所有整数,要求不同的整数用不同的二进制数表示,请问,为了表示 1 到 10000 的所有整数,至少需要多少个二进制位?

答案:14

(2^{14} > 10000)

第二题

问题描述 :

请问在 1 到 2020 中,有多少个数既是 4 的整数倍,又是 6 的整数倍。

答案:168

暴力遍历即可

第三题

问题描述 :

请问有多少个序列满足下面的条件:   

  1. 序列的长度为 5。   
  2. 序列中的每个数都是 1 到 10 之间的整数。   
  3. 序列中后面的数大于等于前面的数。

答案:2002

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int a[10];
int cnt;

void dfs(int pos) {
    if (pos == 6) {
        cnt++;
        return;
    }
    for (int i = 1; i <= 10; ++i)
        if (a[pos - 1] <= i) a[pos] = i, dfs(pos + 1);
}

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0);
    dfs(1);
    cout << cnt;
    return 0;
}

第四题

问题描述 :

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

答案:65

n * ( n - 1 ) / 2

第五题

问题描述:

两个字母之间的距离定义为它们在字母表中位置的距离。例如 A 和 C 的距离为 2,L 和 Q 的距离为 5。对于一个字符串,我们称字符串中两两字符之间的距离之和为字符串的内部距离。 例如:ZOO 的内部距离为 22,其中 Z 和 O 的距离为 11。 请问,LANQIAO 的内部距离是多少?

答案:转化为数字内部暴力循环累加

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int a[7], sum[7], res;
string str;

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0);
    cin >> str;
    for (int i = 0; i < str.size(); i++)
        a[i] = str[i] - 'A';

    for (int i = 0; i < str.size() - 1; i++)
        for (int j = i + 1; j < str.size(); j++)
            res += abs(a[j] - a[i]);
    cout << res << endl;
    return 0;
}

第六题开始为编程题

第六题

问题描述   

现在时间是 a 点 b 分,请问 t 分钟后,是几点几分?

输入格式

输入的第一行包含一个整数 a。   

第二行包含一个整数 b。   

第三行包含一个整数 t。

输出格式

输出第一行包含一个整数,表示结果是几点。   

第二行包含一个整数,表示结果是几分。

样例输入

3 
20 
165 

样例输出

6 
5 

样例输入

3 
20 
175 

样例输出

6 
15 

数据规模和约定   

对于所有评测用例,(0 <= a <= 23, 0 <= b <= 59, 0 <= t), t 分钟后还是在当天。

简答累加取余操作

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
    ios_base::sync_with_stdio(false), cin.tie(0);
    int a, b, t;
    cin >> a >> b >> t;
    b += t;
    cout << (a + b / 60) % 24 << '
'
         << b % 60;
    return 0;
}

第七题

问题描述:

给定一个平行四边形的底边长度 l 和高度 h,求平行四边形的面积。

输入格式

输入的第一行包含一个整数 l,表示平行四边形的底边长度。   

第二行包含一个整数 h,表示平行四边形的高。

输出格式

输出一个整数,表示平行四边形的面积。

(提示:底边长度和高都是整数的平行四边形面积为整数)

样例输入

2 
7 

样例输出

14 

数据规模和约定   

对于所有评测用例,(1 <= l, h <= 100)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
    ios_base::sync_with_stdio(false), cin.tie(0);
    int l, h;
    cin >> l >> h;
    cout << l * h << "
";
    return 0;
}

第八题

问题描述:

小蓝有一张黑白图像,由 n * m 个像素组成,其中从上到下共 n 行,每行从左到右 m 列。每个像素由一个 0 到 255 之间的灰度值表示。

现在,小蓝准备对图像进行模糊操作;

操作的方法为: 对于每个像素,将以它为中心 3 * 3 区域内的所有像素(可能是 9 个像素或少于 9 个像素)求和后除以这个范围内的像素个数(取下整),得到的值就是模糊后的结果。

请注意每个像素都要用原图中的灰度值计算求和。

输入格式

输入的第一行包含两个整数 n, m。   

第 2 行到第 n + 1 行每行包含 m 个整数,表示每个像素的灰度值,相邻整数之间用一个空格分隔。

输出格式

输出 n 行,每行 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)

#include <iostream>
using namespace std;

const int N = 110;
int a[N][N], b[N][N];
int m, n;

int main() {
    cin >> n >> m;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            scanf("%d", &a[i][j]);

    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++) {
            int cnt = 1;
            int res = a[i][j];

            if (i > 0)
                res += a[i - 1][j], cnt++;
            if (i < n - 1)
                res += a[i + 1][j], cnt++;
            if (j > 0)
                res += a[i][j - 1], cnt++;
            if (j < m - 1)
                res += a[i][j + 1], cnt++;
            if (i > 0 && j > 0)
                res += a[i - 1][j - 1], cnt++;
            if (i > 0 && j < m - 1)
                res += a[i - 1][j + 1], cnt++;
            if (i < n - 1 && j > 0)
                res += a[i + 1][j - 1], cnt++;
            if (i < n - 1 && j < m - 1)
                res += a[i + 1][j + 1], cnt++;

            b[i][j] = res / cnt;
        }

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            printf("%d ", b[i][j]);
        }
        puts("");
    }

    return 0;
}

第九题

问题描述:

小蓝负责花园的灌溉工作。花园可以看成一个 n 行 m 列的方格图形。中间有一部分位置上安装有出水管。小蓝可以控制一个按钮同时打开所有的出水管,打开时,有出水管的位置可以被认为已经灌溉好每经过一分钟,水就会向四面扩展一个方格,被扩展到的方格可以被认为已经灌溉好。即如果前一分钟某一个方格被灌溉好,则下一分钟它上下左右的四个方格也被灌溉好。给定花园水管的位置,请问 k 分钟后,有多少个方格被灌溉好?

输入格式

输入的第一行包含两个整数 n, m。   

第二行包含一个整数 t,表示出水管的数量。   

接下来 t 行描述出水管的位置,其中第 i 行包含两个数 r, c 表示第 r 行第 c 列有一个排水管。   

接下来一行包含一个整数 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)

// DFS 版本
#include <bits/stdc++.h>
using namespace std;
using ll        = long long;
int a[110][110] = {0};
int n, m, t, k;
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
void dfs(int x, int y, int time) {
    if (time == k) return;
    // cout << x << " " << y << '
';
    for (int i = 0; i < 4; ++i) {
        int nx = x + dx[i], ny = y + dy[i];
        if (nx < 1 || nx > n || ny < 1 || ny > m) continue;
        a[nx][ny] = 1;
        dfs(nx, ny, time + 1);
    }
}
int main() {
    ios_base::sync_with_stdio(false), cin.tie(0);
    cin >> n >> m >> t;
    vector<pair<int, int>> mp;
    for (int i = 0, x, y; i < t; ++i) {
        cin >> x >> y;
        a[x][y] = 1;
        mp.push_back({x, y});
    }
    // cout << mp.front().first << " " << mp.front().second << "
";
    cin >> k;
    for (auto c : mp) {
        // cout << c.first << " " << c.second << endl;
        dfs(c.first, c.second, 0);
    }
    int cnt = 0;
    for (int i = 1; i <= n; ++i)
        for (int j = 1; j <= m; ++j)
            if (a[i][j]) cnt++;
    cout << cnt;
    return 0;
}
// BFS 版本
#include <iostream>
using namespace std;
#include <cstring>
#include <queue>

const int M = 110, N = 110;
typedef pair<int, int> PII;
queue<PII> q, q_temp;
int a[N][M], re[N][M];
PII t;
int dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, 1, -1}, x, y, ans, n, m;

int bfs(int ans, int time) {

    for (; time > 0; time--) {
        while (q.size()) {
            t = q.front();
            q.pop();
            for (int i = 0; i < 4; i++) {
                int x = t.first + dx[i], y = t.second + dy[i];
                if (x > 0 && x <= n && y > 0 && y <= m && a[x][y] == 0) {
                    a[x][y] = 1;
                    ans++;
                    q_temp.push({x, y});
                }
            }
        }

        while (q_temp.size()) {
            q.push(q_temp.front());
            q_temp.pop();
        }
    }

    return ans;
}

int main() {
    cin >> n >> m;
    memset(a, 0, sizeof a);
    int k;
    cin >> k;
    ans = k;
    while (k--) {
        cin >> x >> y;
        a[x][y] = 1;
        q.push({x, y});
        q_temp.push({x, y});
    }

    int time;
    cin >> time;

    cout << bfs(ans, time);
    return 0;
}

第十题

问题描述 :

小蓝在一个 n 行 m 列的方格图中玩一个游戏。   

开始时,小蓝站在方格图的左上角,即第 1 行第 1 列。   

小蓝可以在方格图上走动,走动时,如果当前在第 r 行第 c 列,他不能走到行号比 r 小的行,也不能走到列号比 c 小的列。同时,他一步走的直线距离不超过3。   

例如,如果当前小蓝在第 3 行第 5 列,他下一步可以走到第 3 行第 6 列、第 3 行第 7 列、第 3 行第 8 列、第 4 行第 5 列、第 4 行第 6 列、第 4 行第 7 列、第 5 行第 5 列、第 5 行第 6 列、第 6 行第 5 列之一。   

小蓝最终要走到第 n 行第 m 列。   

在图中,有的位置有奖励,走上去即可获得,有的位置有惩罚,走上去就要接受惩罚。奖励和惩罚最终抽象成一个权值,奖励为正,惩罚为负。   

小蓝希望,从第 1 行第 1 列走到第 n 行第 m 列后,总的权值和最大。请问最大是多少?

输入格式

输入的第一行包含两个整数 n, m,表示图的大小。   

接下来 n 行,每行 m 个整数,表示方格图中每个点的权值。

输出格式   

输出一个整数,表示最大权值和。

样例输入

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

样例输出

 15 

数据规模和约定   

对于30%的评测用例,(1 <= n, m <= 10);   

对于50%的评测用例,(1 <= n, m <= 20);   

对于所有评测用例,(1 <= n <= 100,-10000 <= 权值 <= 10000)

这个题目有点类似非常经典的数字三角形 ,只是可以走的路径比较多,加个判断就行

相似题型:acwing算法提高课程笔记—数字三角形模型,最长上升子序列模型

#include <iostream>
using namespace std;
using ll = long long;
const int N = 1010;
int dp[N][N], v[N][N];
int n, m;
int main() {
    ios_base::sync_with_stdio(false), cin.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
            cin >> v[i][j];
    dp[0][0] = v[0][0];
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            dp[i][j] = max(dp[i][j], max(dp[i - 1][j] + v[i][j], dp[i][j - 1] + v[i][j]));
            if (i - 2 >= 0 && j - 2 >= 0)
                dp[i][j] = max(dp[i][j], max(dp[i - 2][j] + v[i][j], dp[i][j - 2] + v[i][j]));
            if (i - 3 >= 0 && j - 3 >= 0)
                dp[i][j] = max(dp[i][j], max(dp[i - 3][j] + v[i][j], dp[i][j - 3] + v[i][j]));
        }
    cout << dp[n][m] + v[n][m] << endl;
    return 0;
}

The desire of his soul is the prophecy of his fate
你灵魂的欲望,是你命运的先知。

原文地址:https://www.cnblogs.com/RioTian/p/14606476.html