蓝桥杯C++组怒刷50道真题(填空题)

🌼深夜伤感网抑云 - 南辰Music/御小兮 - 单曲 - 网易云音乐

 

🌼多年后再见你 - 乔洋/周林枫 - 单曲 - 网易云音乐 

18~22年真题,50题才停更,课业繁忙,有空就更,2023/3/18/23:01写下

目录

👊填空题

🌼一,[蓝桥杯2020初赛] 门牌制作

🌼二,[蓝桥杯2020初赛] 既约分数

🌼三,[蓝桥杯2020初赛] 蛇形填数

🌼四,[蓝桥杯2020初赛] 七段码

🌼五,[蓝桥杯2020初赛] 约数个数

🌼六,[蓝桥杯2021初赛] 卡片

🌼七,[蓝桥杯2021初赛] 直线

🌼八,[蓝桥杯2021初赛] 货物摆放

🌼九,[蓝桥杯2021初赛] 路径

🌳Floyd-Warshall 

🌳Dijkstra  AC

🌼十, [蓝桥杯2021初赛] 空间 

🌼十一,[蓝桥杯2022初赛] 裁纸刀

🌼十二,[蓝桥杯2022初赛] 灭鼠先锋

🌼十三, [蓝桥杯2022初赛] 九进制转十进制

🌼十四, [蓝桥杯2022初赛] 顺子日期

🌼十五,[蓝桥杯2022初赛] 排列字母

🌼十六,[蓝桥杯2019初赛]平方和 

🌼十七,[蓝桥杯2019初赛]数列求值

🌼十八,[蓝桥杯2019初赛]最大降雨量

🌼十九,1455: [蓝桥杯2019初赛]迷宫

🌳BFS一  AC

🌳BFS二  AC

🌼二十,1462: [蓝桥杯2019初赛]组队

🌳观察法

🌳DFS

🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉

👊填空题总结 


⚠注意!!!编程题和填空题分成两个博客,毕竟50题,少说5万字,边敲边发布会很卡

编程题链接:  (未完待续)

-------------------------------------------------------

-------------------------------------------------------

👂 空 清新民谣版 - 汪小敏 - 单曲 - 网易云音乐

骗分过样例,暴力出奇迹;暴搜挂着机,打表出省一 (过去式了,看22年A组就知道)

2018,2019,2020,2021,2022年蓝桥杯C++/C组省赛A,B,G组真题

题目链接,题目, 解析,代码 

要参加2023年C++组A组省赛了!希望可以省一,没有也不要紧,还有大二 

当然,如果题目不对胃口,有些ACM银牌的大佬也才省二...对头的话,打铁选手也给你来个国一国二

和我一起刷进蓝桥杯C++A组省一(小声) 

👊填空题

咱先从20年开始

🌼一,[蓝桥杯2020初赛] 门牌制作

P1508 - [蓝桥杯2020初赛] 门牌制作 - New Online Judge (ecustacm.cn)

考虑到蓝桥杯OI赛制(没有反馈),最好自己多试几组例子,比如我,将代码第6行 i <= 2020分别改成23, 1, 19, 32测试了下,如果和草稿本算的一样,就算过了

否则真到比赛时信心满满,感觉自己AC了七八道题,最后连个省二都没就笑了  

#include<iostream>
using namespace std;
int main()
{
    int sum = 0, j;
    for(int i = 1; i <= 2020; ++i) {
        j = i;
        while(j / 10) {
            if(j % 10 == 2)
                sum += 1;
            j /= 10;
        }
        if(j % 10 == 2) sum += 1;
    }
    cout<<sum;
    return 0;
}
624

🌼二,[蓝桥杯2020初赛] 既约分数

P1509 - [蓝桥杯2020初赛] 既约分数 - New Online Judge (ecustacm.cn)

 用辗转相除法求最大公约数

原理: 原来的除数(➗右边的)  /  余数

1997 ÷ 615 = 3 (余 152)
615 ÷ 152 = 4(余7)
152 ÷ 7 = 21(余5)
7 ÷ 5 = 1 (余2)
5 ÷ 2 = 2 (余1)
2 ÷ 1 = 2 (余0)
至此,最大公约数为1
#include<iostream>
using namespace std;
int com(int x, int y)
{
    while(x % y) { //辗转相除法
        int z = x % y;
        x = y;
        y = z;
    }
    return y;
}
int main()
{
    int sum = 0;
    for(int i = 1; i <= 2020; ++i)
        for(int j = 1; j <= 2020; ++j)
            if(com(i, j) == 1) sum++;
    cout<<sum;
    return 0;
}
2481215

🌼三,[蓝桥杯2020初赛] 蛇形填数

P1510 - [蓝桥杯2020初赛] 蛇形填数 - New Online Judge (ecustacm.cn)

容易发现,数字按照 右-->左下-->下-->右上 的规律递增 

加个判断边界的条件即可

先画到45,可知,找第n行n列, i, j 需要遍历到2 * n - 1 

#include<iostream>
using namespace std;
int a[1000][1000];
int main()
{
    a[1][1] = 1;
    int m = 1;
    for(int i = 1, j = 1; i <= 40 && j <= 40;) {
            //右
            a[i][++j] = ++m;
            //左下
            while(1) {
                a[++i][--j] = ++m;
                if(j == 1) break;
            }
            //下
            a[++i][j] = ++m;
            //右上
            while(1) {
                a[--i][++j] = ++m;
                if(i == 1) break;
            }
        }
    cout<<a[20][20];
    return 0;
}
761

🌼四,[蓝桥杯2020初赛] 七段码

P1511 - [蓝桥杯2020初赛] 七段码 - New Online Judge (ecustacm.cn)

第一次做,猜了63种,错了,7 + 10 + 14 + 14 + 10 + 7 + 1 = 63

错在哪里呢,错在3,4,5段发光

而且由于不发光部分不需要连通,所以 3段 != 4段, 2段 != 5段

这道题单靠猜,90%的人都做不对,很容易就漏掉几种或者想当然

当然代码我也不会😂 

来个别人的AC代码把

#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char *argv[])
{
  // 请在此输入您的代码
  int sum = 0;
     
    //有一段二极管发光; a,b,c,d,e,f,g
    int l1 = 7;
    //有两段二极管发光; ab,af,bc,bg,cg,cd,de,eg,ef,fg
    int l2 = 10;
    //有三段二极管发光; abf,abc,abg,afg,afe,bcd,bcg,bgf,bge,cgd,cgf,cge,cde,cdg,deg,def,efg
    int l3 = 16;//
    //有四段二极管发光; abcd,abcg,abcf,abge,abgf,abfe,afeg,bcde,bcdg,bcgf,bcge,bged,bgef,cdef,cdeg,cdgf,cgfa,cgfe,defg,defa
    int l4 = 20;
    //有五段二极管发光即有两端不发光; ab,ac,ad,ae,af,ag,bc,bd,be,bg,cd,cf,cg,de,df,dg,ef,eg,fg
    int l5 = 19;//
    //有六段二极管发光即有一端不发光; a,b,c,d,e,f,g
    int l6 = 7;//(找一段二极管不发光的:)
    //第七种情况,全部发光
    int l7 = 1;
     
    sum = l1 + l2 + l3 + l4 + l5 + l6 + l7;
    printf("%d\n", sum);
  return 0;
}

🌼五,[蓝桥杯2020初赛] 约数个数

P1514 - [蓝桥杯2020初赛] 约数个数 - New Online Judge (ecustacm.cn)

#include<iostream>
using namespace std;
int main()
{
    int sum = 0;
    for(int i = 1; i <= 1200000; ++i)
        if(1200000 % i == 0) sum++;
    cout<<sum;
    return 0;
}
96

到21年 

🌼六,[蓝桥杯2021初赛] 卡片

P1550 - [蓝桥杯2021初赛] 卡片 - New Online Judge (ecustacm.cn)

初始化a[10]为2021,对应着0~9,int k = i;  a[k % 10]--即可 

但是有个问题,代码虽然输出了正确答案,但是提交时显示编译错误,原来是语言选了C 

#include<iostream>
using namespace std;
int a[10];
int main()
{
    for(int i = 0; i <= 9; ++i)
        a[i] = 2021; //初始化
    int flag = 0;
    for(int i = 1;; ++i) { //从1开始遍历
        int k = i;
        while(k) {
            a[k % 10]--;
            k /= 10;
        }
        for(int j = 0; j <= 9; ++j)
            if(a[j] < 0) {
                cout<<i - 1;
                flag = 1; //到头了
                break;
            }
        if(flag) break;
    }
    return 0;
}
3181

🌼七,[蓝桥杯2021初赛] 直线

P1551 - [蓝桥杯2021初赛] 直线 - New Online Judge (ecustacm.cn)

注意,除了下标和计数的now,其他都声明为double

而且第一次看成斜率相同算同一条直线了...

如果只是判断多少种斜率,最简单的set即可

但这里斜率 + 截距才能确定一条直线

一开始...犯了个重名的小错误, 找了半小时 + 百度 才找出来...

set<pair<double, double>>b; //斜率k, 截距b
    for(int i = 0; i < 420; ++i)
        for(int j = 0; j < 420; ++j) {
            if(a[i].x != a[j].x && a[i].y != a[j].y) {
                double k = (a[i].y - a[j].y) / (a[i].x - a[j].x);
                double b = a[i].y - k * a[i].x;
                b.insert({k, b});
            }
        }

报错error: request for member 'insert' in 'b', which is of non-class type 'double'

意思是, set变量名b和循环里面的double b重复了

修改后,第一次提交, 错了....(原因会在后面分析)

错误代码

#include<iostream>
#include<set> //set<>b;
using namespace std;
struct place
{
    double x, y; //横纵坐标
};
int main()
{
    struct place a[430];
    int now = 0;
    //读入420个点
    for(double i = 0; i <= 19; ++i)
        for(double j = 0; j <= 20; ++j) {
            a[now].x = i;
            a[now++].y = j;
        }
    //判断不同的直线
    set<pair<double, double>>line; //斜率k, 截距b
    for(int i = 0; i < 420; ++i)
        for(int j = 0; j < 420; ++j) {
            if(a[i].x != a[j].x && a[i].y != a[j].y) {
                double k = (a[i].y - a[j].y) / (a[i].x - a[j].x);
                double b = a[i].y - k * a[i].x;
                line.insert({k, b});
            }
        }
    cout<<line.size() + 20 + 21; //加上竖和横
    return 0;
}
48953

而正确答案是40257

错误原因是double精度丢失 

k那里没问题, 问题是b那里,解决方案是

b = y1 - (y2 - y1) / (x2 - x1) * x1 ----> b = (y1 * (x2 - x1) - (y2 - y1) * x1) / (x2 - x1)

猜测是先除再减,会丢失更多精度.... 

AC代码 

当然,我用结构体写的有点乱了,意思就是这么个意思, y = kx + b, k = (y2 - y1) / (x2 - x1) 

核心思路就是斜率和截距确定一条直线 + set排除重合元素 + pair 

#include<iostream>
#include<set> //set<>b;
using namespace std;
struct place
{
    double x, y; //横纵坐标
};
int main()
{
    struct place a[430];
    int now = 0;
    //读入420个点
    for(double i = 0; i <= 19; ++i)
        for(double j = 0; j <= 20; ++j) {
            a[now].x = i;
            a[now++].y = j;
        }
    //判断不同的直线
    set<pair<double, double>>line; //斜率k, 截距b
    for(int i = 0; i < 420; ++i)
        for(int j = 0; j < 420; ++j) {
            if(a[i].x != a[j].x && a[i].y != a[j].y) { //排除横竖直线
                double k = (a[i].y - a[j].y) / (a[i].x - a[j].x);
                double b = (a[i].y * (a[i].x - a[j].x) -
                            (a[i].y - a[j].y) * a[i].x) / (a[i].x - a[j].x);
                line.insert({k, b});
            }
        }
    cout<<line.size() + 20 + 21; //加上竖和横
    return 0;
}
40257

🌼八,[蓝桥杯2021初赛] 货物摆放

P1552 - [蓝桥杯2021初赛] 货物摆放 - New Online Judge (ecustacm.cn)

虽然填空题不看复杂度,但是这么大的数,直接O(n^3)暴力肯定不行

容易发现,虽然是三个数,还是能用找因子的方法,用一个数组保存因子即可 

因子用取余 == 0的方式判断 

第一次敲完, 输出0.....然后一看int a[10000]里,单个数不能超过int,所以改long long就好了

#include<iostream>
#include<cmath> //sqrt()
using namespace std;
long long a[10010];
int main()
{
    long long n = 2021041820210418, sum = 0, now = 0;
    for(long long i = 1; i < sqrt(n); ++i)
        if(n % i == 0) { //找出因子
            a[now++] = i;
            if(i * i != n) //判断另一个因子
                a[now++] = n / i;
        }
    for(int i = 0; i < now; ++i)
        for(int j = 0; j < now; ++j)
            for(int k = 0; k < now; ++k)
                if(a[i] * a[j] * a[k] == n) sum++;
    cout<<sum;
    return 0;
}
2430

🌼九,[蓝桥杯2021初赛] 路径

P1553 - [蓝桥杯2021初赛] 路径 - New Online Judge (ecustacm.cn)  

看到最短路, 正好前天刚学了Floyd-WarshallDijkstra , 盘它

不会的可以看看这个博客

(5条消息) 最短路之Floyd-Warshall(10张图解)_码龄11天的博客-CSDN博客

(2条消息) 最短路之Dijkstra(15张图解)_迪杰斯特拉算法求最短路径图解_码龄?天的博客-CSDN博客

1,floyd是求多源最短路的

而且Floyd和Dijkstra都适用于稠密图(本题显然是稠密图)

假设n个顶点, m条边

看到没,这个才是稠密图(m >= n^2)

而一般的10个顶点,20条边这种,都是稀疏图(m << n^2)

Floyd核心思路还是中转 

2,将"路"读入二维数组e;  

3,第三个我们借辗转相除法间接求出最小公倍数

第一次敲完,无论是顶点1到2021还是顶点1到100,输出都是1e8,肯定哪里错了 

然后我对每一部分进行验算 

1,求公倍数函数com()没问题 

2,Floyd那里有问题 

//利用中转求最短路
for(int k = 1; k <= 2021; ++k)  //通过所有点中转
    if(e[1][k] + e[k][2021] < e[1][2021])

为什么这段代码会让每次都输出无穷值呢?

因为你误以为Floyd可以求单源最短路. 它必须先通过求出多源最短路,才能找到单源的答案

只能用n^3先算出所有点的最短路,才能求1到2021的最短路

🌳Floyd-Warshall 

(本地AC, OJ上时间超限)

#include<iostream>
#include<cmath> //abs()
using namespace std;
int e[2050][2050];
int inf = 1e9; //infinity无穷

int com(int x, int y)
{
    int a = x, b = y;
    while(y) {
        int z = x % y;
        x = y;
        y = z; //最后的x为公因数
    }
    return a * b / x; //最小公倍数
}

int main()
{
    //初始化
    for(int i = 1; i <= 2021; ++i)
        for(int j = 1; j <= 2021; ++j) {
            if(i == j) e[i][j] = 0; //自己到自己距离为0
            else e[i][j] = inf;
        }
    //读入边的长度
    for(int i = 1; i <= 2021; ++i)
        for(int j = 1; j <= 2021; ++j) {
            if(abs(i - j) <= 21 && i != j) {
                e[i][j] = com(i, j);
                e[j][i] = e[i][j]; //无向边
            }
        }
    //利用中转求最短路(Floyd核心)
    for(int k = 1; k <= 2021; ++k) //通过所有点中转
        for(int i = 1; i <= 2021; ++i)
            for(int j = 1; j <= 2021; ++j)
                if(e[i][k] + e[k][j] < e[i][j])
                    e[i][j] = e[i][k] + e[k][j];
    cout<<e[1][2021];
    return 0;
}

等了10秒才出结果(不要提交这个,这个在本地算出答案,只提交答案即可)

10266837

 提交时,怕超时,所以直接printf()

AC代码 

#include<iostream>
using namespace std;
int main()
{
    cout<<10266837;
    return 0;
}

 尽管时间复杂度达O(n^3), 大约是(2*10^3)^3 = 8e9, 也不是很大,毕竟顶点个数才2021个

所以填空题,一般建议暴力解决 + printf() 

------------------------------------------------------------------ 

下面,我再用Dijkstra做下这题 

Dijkstra的科普博客(6条消息) 最短路之Dijkstra(15张图解)_码龄11天的博客-CSDN博客

Dijkstra原理是贪心,而Floyd是动态规划 

1,初始化数组

2,循环

(1)确定源点到最近点的最短路径

(2)从刚被确定的点"出边"

🌳Dijkstra  AC

#include<iostream>
#include<cmath> //abs()
using namespace std;
int e[2050][2050], dis[2050], book[2050];
int inf = 1e9; //infinity无穷

int com(int x, int y)
{
    int a = x, b = y;
    while(y) {
        int z = x % y;
        x = y;
        y = z; //最后的x为公因数
    }
    return a * b / x; //最小公倍数
}
int main()
{
    //初始化
    for(int i = 1; i <= 2021; ++i)
        for(int j = 1; j <= 2021; ++j) {
            if(i == j) e[i][j] = 0; //自己到自己距离为0
            else e[i][j] = inf;
        }
    //读入边的长度
    for(int i = 1; i <= 2021; ++i)
        for(int j = 1; j <= 2021; ++j) {
            if(abs(i - j) <= 21 && i != j) {
                e[i][j] = com(i, j);
                e[j][i] = e[i][j]; //无向边
            }
        }
    //初始化book和dis数组
    for(int i = 1; i <= 2021; ++i) {
        book[i] = 0;
        dis[i] = e[1][i];
    }
    //Dijkstra
    for(int i = 1; i <= 2020; ++i) { //n - 1次确定最短路
        int Min = inf;
        int u;
        //找确定值
        for(int j = 2; j <= 2021; ++j) { //1为源点,从下一个开始
            if(book[j] == 0 && dis[j] < Min) {
                Min = dis[j];
                u = j;
            }
        }
        book[u] = 1; //源点1号到u号的距离确定为最短路程
        //从刚确定的点出边
        for(int k = 2; k <= 2021; ++k) {
            //两点连通且可更新
            if(e[u][k] < inf && dis[k] > dis[u] + e[u][k])
                dis[k] = dis[u] + e[u][k];
        }
    }
    cout<<dis[2021];
    return 0;
}
10266837

时间复杂度O(n^2),2021个点的数据量,直接提交也能过了

🌼十, [蓝桥杯2021初赛] 空间 

P1555 - [蓝桥杯2021初赛] 空间 - New Online Judge (ecustacm.cn)

一个32位二进制整数 = 4B, 1KB = 1024B,  1MB = 1024KB

所以  256MB = 256 * 1024 * 1024 / 4   个32位二进制整数 

#include<iostream>
using namespace std;
int main()
{
    cout<<256 * 256 * 1024;
    return 0;
}

到22年了

🌼十一,[蓝桥杯2022初赛] 裁纸刀

P2021 - [蓝桥杯2022初赛] 裁纸刀 - New Online Judge (ecustacm.cn)

🌼十二,[蓝桥杯2022初赛] 灭鼠先锋

P2022 - [蓝桥杯2022初赛] 灭鼠先锋 - New Online Judge (ecustacm.cn)

22年A组前两道填空题,放个以前的博客👇

(8条消息) 2022蓝桥杯省赛C++A组初尝试_码龄11天的博客-CSDN博客

🌼十三, [蓝桥杯2022初赛] 九进制转十进制

P2031 - [蓝桥杯2022初赛] 九进制转十进制 - New Online Judge (ecustacm.cn)

先让我们回忆下,十六进制转10怎么转的?

首先作为字符串输入 ,如果由0~9组成的十六进制数, 只需

if(s[i] >= '0' && s[i] <= '9') 
    sum += s[i] - '0';
......
sum *= 16;

接下来有样学样就行,关键别人还给了确定的数

 2022(9) = 2 * 9^0 + 2 * 9^1 + 0 * 9^2 + 2 * 9^3

#include<iostream>
using namespace std;
int main()
{
    int sum = 2 * 1 + 2 * 9 + 0 + 2 * 9*9*9;
    cout<<sum;
    return 0;
}

粗心就会败北,第一次提交还写错个1,,,,真到蓝桥杯,一定要细心细心再细心

在草稿纸列清楚条条框框和细节,想尽可能多的, 特殊的样例 

🌼十四, [蓝桥杯2022初赛] 顺子日期

P2032 - [蓝桥杯2022初赛] 顺子日期 - New Online Judge (ecustacm.cn)

一开始我以为是任意年份,,,写了一堆字符串验证

然后看到了2022

先梳理思路,2022肯定构不成顺子,如果最后一个2开始构成顺子,2,3,4,需要第34月

也不可能 

细心细心再细心,不要想当然老老实实列出所有情况 

所以只能从月,日入手:

1,01月 + 20~29日(10种)

2,10月 + 12日(1种)

3,11月 + 23日(1种)

4,12月 + 30~31日 (2种)

10 + 1 + 1 + 2 = 14

#include<iostream>
using namespace std;
int main()
{   
    cout<<14;
    return 0;
}

 细心的人,高考能拿多50分;而粗心,足以使一个国二变成省二

🌼十五,[蓝桥杯2022初赛] 排列字母

P2041 - [蓝桥杯2022初赛] 排列字母 - New Online Judge (ecustacm.cn)

标签:入门题,模拟 

 按字符数组输入字符串,strlen()求字符数组字符串长度,sort()排序

#include<iostream>
#include<algorithm> //sort()
#include<cstring> //strlen()
using namespace std;
int main()
{
    char s[20200] = "WHERETHEREISAWILLTHEREISAWAY";
    sort(s, s + strlen(s));
    cout<<s;
    return 0;
}
AAAEEEEEEHHHIIILLRRRSSTTWWWY

当然,这种填空题,自己直接排序,敲上去printf()也可

🌼十六,[蓝桥杯2019初赛]平方和 

P1452 - [蓝桥杯2019初赛]平方和 - New Online Judge (ecustacm.cn)

#include<iostream>
typedef long long LL;
using namespace std;
bool check(LL  n)
{
    while(n) {
        LL m = n % 10;
        if(m == 0 || m == 1 || m == 2 || m == 9)
            return true;
        n /= 10;
    }
    return false;
}
int main()
{
    LL sum = 0;
    for(LL i = 1; i <= 2019; ++i) {
        if(check(i))
            sum += i * i;
    }
    cout<<sum;
    return 0;
}
2658417853

当然,最后提交时,我是这样提交的

#include <iostream>
using namespace std;
int main()
{
    cout<<2658417853;
    return 0;
}

🌼十七,[蓝桥杯2019初赛]数列求值

P1453 - [蓝桥杯2019初赛]数列求值 - New Online Judge (ecustacm.cn)

第一次,求出0115,做错了。。

错误代码 

#include<iostream>
typedef long long LL;
using namespace std;
LL a[20200000];
int main()
{
    a[1] = 1; a[2] = 1; a[3] = 1;
    for(int i = 4; i <= 20190324; ++i) {
        a[i] = a[i - 1] + a[i - 2] + a[i - 3];
    }
    cout<<a[20190324];
    return 0;
}
5268603393216230115

难道是超限了?应该是,考虑到题目说只需要最后四项,因为边取余边加不影响取余结果

所以我们在每一步加上取余10000

所以以后遇到,累乘或累加最后几位数字的,每算一步取余一次 

因为边加边取余,或者边乘边取余,结果不变

#include<iostream>
typedef long long LL;
using namespace std;
LL a[20200000];
int main()
{
    a[1] = 1; a[2] = 1; a[3] = 1;
    for(int i = 4; i <= 20190324; ++i) {
        a[i] = (a[i - 1] + a[i - 2] + a[i - 3]) % 10000; //注意这里
    }
    cout<<a[20190324];
    return 0;
}
4659

AC代码

#include <iostream>
using namespace std;
int main()
{
    cout<<4659;
    return 0;
}

🌼十八,[蓝桥杯2019初赛]最大降雨量

P1454 - [蓝桥杯2019初赛]最大降雨量 - New Online Judge (ecustacm.cn)

这是一道考研细心的题

审题一定要认真啊。。。

🌳Wrong Answer

读题时就感觉最大值是多少有点怪怪的,但没有细想,我把最大“降雨量”求出来不就完了?

所以,读题时感觉怪怪的地方,一定要多读几遍

搞清楚题目问的是什么具体过程是什么

要亲自模拟一遍

如上图,这种情况降雨量最大,先草稿本算一遍,再代码来一次,一样,信心慢慢提交

#include<iostream>
using namespace std;
int main()
{
    int ans = 0;
    for(int i = 22; i <= 46; i += 4)
        ans += i;
    cout<<ans;
    return 0;
}
238

Wa!

🌳Accepted

看清楚,你所求出的238是最大的能量和,而降雨量为7周能量中位数,所以是34

#include<iostream>
using namespace std;
int main()
{
    cout<<"34";
    return 0;
}

🌼十九,1455: [蓝桥杯2019初赛]迷宫

P1455 - [蓝桥杯2019初赛]迷宫 - New Online Judge (ecustacm.cn)

这里介绍两种获得文件数据的方法

文件数据 oj.ecustacm.cn/upload/file/20200122/20200122134020_61830.txt

分析

 最短路杜绝dfs,指数级复杂度

下面针对是否读文件的2种情况,用bfsAC(01方阵最短路一般用bfs

→ (5条消息) 《啊哈算法第四章之bfs》(17张图解)_千帐灯无此声的博客-CSDN博客

当然,由于填空题不考察时间复杂度(最后printf就行)所以一开始我还考虑了dijstra和Floyd

但这是01最短路边权为1的地图,考虑bfs的模拟过程,显然bfs最合适

而Dij和Floy,做边权不为1的更合适

考察

1,读取数据

for(int i=0;i<n;i++)
    cin>>maze[i];

考虑到字符串按换行区分,整块粘贴过去就行

2,BFS模板,这个都要会

3,如何得到路径,网上搜了下看不懂(或者说懒得看了)

用自认为简单易懂的方式写了个(解释在注释里

1,不用读文件

🌳BFS一  AC

我习惯用用数组模拟队列,就不用stl的queue了

关于输出路径,有个坑,第一次我少输出了第一步的D,因为最后得到路径写成这样了

while(que[tail].f) {
        ans += que[tail].al; //字符的连接
        tail = que[tail].f; //更新队尾为上一个点
    }

至于为什么会少输出第一步呢,请看图

假设最短路径为(1, 1), (2, 1), (3, 1), (4, 1),假设此时来到(3, 1)

于是字符串ans加上了(到达(3, 1) 需要走的)方向,然后tail = (2, 1)所代表的下标(父坐标)

此时的que[tail].f 就已经是第一个点的下标了,在代码中也就是0,所以会漏了第一步

修改

while(que[tail].f) --> while(tail)

原始代码

然而直接提交显示答案错误(超时是不可能超时的),因为本题没有输入,它的本意就是考察读取文件数据传入字符变量

#include<iostream>
using namespace std;
int tx, ty, flag, vis[100][100];
string maze[30], ans;
struct node
{   //只要求输出最短路的路线,不要求输出具体步数,不用s
    int x, y, f; //横坐标, 纵坐标, 父坐标
    char al; //方向字母
};
int main()
{
    for(int i = 0; i < 30; ++i)
        cin>>maze[i];
    struct node que[1510]; //30 * 50
    //方向数组, 由于D<L<R<U, 需要按这个顺序
    int next[4][2] = {{1,0},{0,-1},{0,1},{-1,0}};
    char dir[4] = {'D','L','R','U'}; //方向字母
    //初始化队列
    int head = 0, tail = 0;
    //队列插入迷宫入口坐标
    que[tail].x = 0;
    que[tail].y = 0;
    que[tail].f = 0;
    que[tail].al = '0';
    tail++;
    //队列不为空
    while(head < tail) {
        //枚举4个方向
        for(int i = 0; i < 4; ++i) {
            //新的坐标
            tx = que[head].x + next[i][0];
            ty = que[head].y + next[i][1];
            //超出范围
            if(tx < 0 || ty < 0 || tx >= 30 || ty >= 50)
                continue;
            //未访问过且不为障碍
            if(vis[tx][ty] == 0 && maze[tx][ty] == '0') {
                vis[tx][ty] = 1; //标记
                que[tail].x = tx;
                que[tail].y = ty;
                que[tail].f = head;
                que[tail].al = dir[i];
                tail++;
                //BFS不需要取消标记, 只入队1次
            }
            //到达终点
            if(tx == 29 && ty == 49) {
                flag = 1;
                break;
            }
        }
        if(flag) break;
        head++; //后续点的扩展
    }
    //用ans字符串保存从尾到头输出的路径
    tail--; //最后的tail是队尾下一个,所以-1
    while(tail) {
        ans += que[tail].al; //字符的连接
        tail = que[tail].f; //更新队尾为上一个点
    }
    for(int i = ans.size() - 1; i >= 0; --i)
        cout<<ans[i];
    return 0;
}

直接将输出的答案复制,cout就好,所以填空题尽量本地DevC++得到答案后,再专门cout吧

貌似填空题一般也没有输入,只有输出 

输入输出

11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000
DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR

AC  代码

#include<iostream>
using namespace std;
int main()
{
    cout<<"DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR";
    return 0;
}

2,读文件

🌳BFS二  AC

读入文件只需要增加这些操作

maze.txt要和代码文件在同一目录下

#include<fstream>
...
//读取文件数据
    ifstream infile("maze.txt"); //打开maze.txt文件
    //按行读入maze.txt文件的字符串, 保存到maze数组中
    for(int i = 0; i < 30; ++i)
        getline(infile, maze[i]);

👆

原始代码

#include<iostream>
#include<fstream>
using namespace std;
int tx, ty, flag, vis[100][100];
string maze[30], ans;
struct node
{   //只要求输出最短路的路线,不要求输出具体步数,不用s
    int x, y, f; //横坐标, 纵坐标, 父坐标
    char al; //方向字母
};
int main()
{
    //读取文件数据
    ifstream infile("maze.txt"); //打开maze.txt文件
    //按行读入maze.txt文件的字符串, 保存到maze数组中
    for(int i = 0; i < 30; ++i)
        getline(infile, maze[i]);

    struct node que[1510]; //30 * 50
    //方向数组, 由于D<L<R<U, 需要按这个顺序
    int next[4][2] = {{1,0},{0,-1},{0,1},{-1,0}};
    char dir[4] = {'D','L','R','U'}; //方向字母
    //初始化队列
    int head = 0, tail = 0;
    //队列插入迷宫入口坐标
    que[tail].x = 0;
    que[tail].y = 0;
    que[tail].f = 0;
    que[tail].al = '0';
    tail++;
    //队列不为空
    while(head < tail) {
        //枚举4个方向
        for(int i = 0; i < 4; ++i) {
            //新的坐标
            tx = que[head].x + next[i][0];
            ty = que[head].y + next[i][1];
            //超出范围
            if(tx < 0 || ty < 0 || tx >= 30 || ty >= 50)
                continue;
            //未访问过且不为障碍
            if(vis[tx][ty] == 0 && maze[tx][ty] == '0') {
                vis[tx][ty] = 1; //标记
                que[tail].x = tx;
                que[tail].y = ty;
                que[tail].f = head;
                que[tail].al = dir[i];
                tail++;
                //BFS不需要取消标记, 只入队1次
            }
            //到达终点
            if(tx == 29 && ty == 49) {
                flag = 1;
                break;
            }
        }
        if(flag) break;
        head++; //后续点的扩展
    }
    //用ans字符串保存从尾到头输出的路径
    tail--; //最后的tail是队尾下一个,所以-1
    while(tail) {
        ans += que[tail].al; //字符的连接
        tail = que[tail].f; //更新队尾为上一个点
    }
    for(int i = ans.size() - 1; i >= 0; --i)
        cout<<ans[i];
    return 0;
}

当然,最后提交还是要这个,因为蓝桥杯OJ不包含maze.txt这个文件

#include<iostream>
using namespace std;
int main()
{
    cout<<"DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR";
    return 0;
}

🌼二十,1462: [蓝桥杯2019初赛]组队

P1462 - [蓝桥杯2019初赛]组队 - New Online Judge (ecustacm.cn)

team.txt链接 oj.ecustacm.cn/upload/file/20200122/20200122152423_34129.txt

思路

有点类似全排列,给定5个盒子,每个盒子一个数字,求最大的和

用dfs好了

当然,5 * 20这么点数据,100个数,一个一个数也给它数出来了

如果是50 * 50的数据量可能就算了

🌳观察法

注意,一个人只能同时打一个位置

我把每一列最高分的2~3个标记出来,如果某个队员只在唯一一个位置最高分,就选这个队员

当然,观察可知,17号选3号位的99分  或者  1号位的98分   是等价的 

98 + 99 + 98 + 97 + 98 = 490

#include<iostream>
using namespace std;
int main()
{
    cout<<490;
    return 0;
}

🌳DFS

1,数据直接复制到代码里

这种办法还行,就是加 ',' 有些烦,注意还得删去第一列的编号

#include<iostream>
using namespace std;
int book[30], ans; //book[]的大小要大于20
int c[20][5] = {
{97, 90, 0 ,0, 0},
{92, 85, 96, 0, 0},
{0, 0, 0, 0, 93},
{0, 0, 0, 80, 86},
{89, 83, 97, 0, 0},
{82, 86, 0, 0, 0},
{0, 0, 0, 87, 90},
{0, 97, 96, 0, 0},
{0, 0, 89, 0, 0},
{95, 99, 0, 0, 0},
{0, 0, 96, 97, 0},
{0, 0, 0, 93, 98},
{94, 91, 0, 0, 0},
{0, 83, 87, 0, 0},
{0, 0, 98, 97, 98},
{0, 0, 0, 93, 86},
{98, 83, 99, 98, 81},
{93, 87, 92, 96, 98},
{0, 0, 0, 89, 92},
{0, 99, 96, 95, 81}
};
void dfs(int step, int now) //当前第几号位
{
    if(step == 6) { //完成5个位置后, 结束递归
        ans = max(ans, now);
        return; //递归回上一个位置
    }
    //遍历
    for(int i = 0; i < 20; ++i) {
        if(book[i] == 0) { //第i号队员没被选上
            book[i] = 1; //标记
            dfs(step + 1, now + c[i][step - 1]); //递归
            book[i] = 0; //取消标记
        }
    }
}
int main()
{
    dfs(1, 0); //从1号位开始
    cout<<ans;
    return 0;
}

注意第36行step要-1,因为c[20][5]里,第几列的下标从0开始,第5列的下标是4,所以step == 5时

下标应该为4,所以-1,否则数组超限会输出491

2,读取同一目录下的文件

关于将20行6列的team.txt读取到c[20][6]这个二维数组中

操作

#include<fstream> //ifstream读取文件
...
//ifstream打开文件,命名为infile
    ifstream infile("team.txt"); //文件名作为参数,""括起来
    //读取文件每一个数字
    for(int i = 0; i < 20; ++i)
        for(int j = 0; j < 6; ++j)
            infile >> c[i][j]; //存储到二维数组c
    infile.close(); //关闭文件

原始代码

#include<iostream>
#include<fstream> //ifstream读取文件
using namespace std;
int book[30], ans, c[20][6];
void dfs(int step, int now) //当前第几号位
{
    if(step == 6) { //完成5个位置后, 结束递归
        ans = max(ans, now);
        return; //递归回上一个位置
    }
    //遍历
    for(int i = 0; i < 20; ++i) {
        if(book[i] == 0) { //第i号队员没被选上
            book[i] = 1; //标记
            dfs(step + 1, now + c[i][step]); //递归
            book[i] = 0; //取消标记
        }
    }
}
int main()
{
    //ifstream打开文件,命名为infile
    ifstream infile("team.txt"); //文件名作为参数,""括起来
    //读取文件每一个数字
    for(int i = 0; i < 20; ++i)
        for(int j = 0; j < 6; ++j)
            infile >> c[i][j]; //存储到二维数组c
    infile.close(); //关闭文件

    dfs(1, 0); //从1号位开始
    cout<<ans;
    return 0;
}

AC  代码

#include<iostream>
using namespace std;
int main()
{
    cout<<490;
    return 0;
}

🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉🍉

👊填空题总结 

1,预测23年题型

做了那么多2018,2019,2020,2021,2022的填空题,2023蓝桥杯省赛的填空题是什么呢,让我们猜猜看?和2023有关的前缀和或者字符串或者模拟?  

2,审题细心是关键

如果你只会模板题和暴力,那你绝对无缘国奖(虽然目前我的目标是A组省二)

首先,模板题可能出现各种变式,需要仔细观察题目,去模拟一下过程,再考虑对模板进行增删改

其次,读题不细心,导致,明明会做的,拿不到分,它让你输出A就别输出B(虽然A,B你都求出来了)

3,按行读取文件字符串,保存到字符串数组中

我先声明了string maze[30],然后将同一目录下maze.txt中的30行字符串读入maze[30]

#include<fstream>
string maze[30];
...
//读取文件数据
    ifstream infile("maze.txt"); //打开maze.txt文件
    //按行读入maze.txt文件的字符串, 保存到maze数组中
    for(int i = 0; i < 30; ++i)
        getline(infile, maze[i]);

按单个数字读取

#include<fstream> //ifstream读取文件
int c[20][6];
...
//ifstream打开文件,命名为infile
    ifstream infile("team.txt"); //文件名作为参数,""括起来
    //读取文件每一个数字
    for(int i = 0; i < 20; ++i)
        for(int j = 0; j < 6; ++j)
            infile >> c[i][j]; //存储到二维数组c
    infile.close(); //关闭文件

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/1606.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【C++】智能指针

文章目录&#x1f4d6; 前言1. 智能指针的引入1.1 内存泄露的危害&#xff1a;1.2 异常安全中的内存泄露&#xff1a;1.3 RAII思想&#xff1a;1.3 拦截异常解决不了的内存泄漏&#xff1a;1.4 智能指针解决&#xff1a;2. 智能指针的拷贝2.1 直接拷贝的问题&#xff1a;2.2 au…

STM32实战项目-触摸按键

前言&#xff1a; 通过触摸按键控制LED灯以及继电器&#xff0c;具体实现功能如下&#xff1a; 1、触摸按键1单击与长按&#xff0c;控制LED1&#xff1b; 2、触摸按键2单击与长按&#xff0c;控制LED2; 3、触摸按键3单击与长按&#xff0c;控制LED3; 4、触摸按键4单击与长…

详解Spring、SpringBoot、SpringCloud三者的联系与区别

一、Spring Spring 是一个轻量级的Java 开发框架&#xff0c;主要依存于SSM 框架&#xff0c;即Spring MVC Spring Mybatis&#xff0c;定位很明确&#xff0c;Spring MVC主要负责view 层的显示&#xff0c;Spring 利用IOC 和AOP 来处理业务&#xff0c;Mybatis则是数据的持…

跨域解决方案

跨域解决方案 1.跨域基本介绍 文档&#xff1a;https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS 跨域问题是什么&#xff1f; 一句话&#xff1a;跨域指的是浏览器不能执行其他网站的脚本&#xff0c;它是由浏览器的同源策略造成的&#xff0c;是浏览器对 javascr…

数据结构 | 栈的中缀表达式求值

目录 什么是栈&#xff1f; 栈的基本操作 入栈操作 出栈操作 取栈顶元素 中缀表达式求值 实现思路 具体代码 什么是栈&#xff1f; 栈是一种线性数据结构&#xff0c;具有“先进后出”&#xff08;Last In First Out, LIFO&#xff09;的特点。它可以看作是一种受限的…

“国产版ChatGPT”文心一言发布会现场Demo硬核复现

文章目录前言实验结果一、文学创作问题1 :《三体》的作者是哪里人&#xff1f;问题2&#xff1a;可以总结下三体的核心内容吗&#xff1f;如果要续写的话&#xff0c;可以从哪些角度出发&#xff1f;问题3&#xff1a;如何从哲学角度来进行续写&#xff1f;问题4&#xff1a;电…

学习28个案例总结

学习前 对于之前遇到的问题没有及时总结&#xff0c;导致做什么事情都是新的一样。没有把之前学习到接触到的内容应用上。通过这次对28个案例的学习。把之前遇到的问题总结成自己的经验&#xff0c;在以后的开发过程中避免踩重复性的坑。多看帮助少走弯路。 学习中 对28个案例…

2023年安徽省中职网络安全跨站脚本攻击

B-4&#xff1a;跨站脚本攻击 任务环境说明&#xff1a; √ 服务器场景&#xff1a;Server2125&#xff08;关闭链接&#xff09; √ 服务器场景操作系统&#xff1a;未知 √ 用户名:未知 密码&#xff1a;未知 1.访问服务器网站目录1&#xff0c;根据页面信息完成条件&am…

Shader基础

参考文章:Unity着色器介绍 Shader基础 Properties 声明格式 [optional: attribute] name(“display text in Inspector”, type name) default value 属性类型 Color&#xff1a;颜色属性&#xff0c;表示 RGBA 颜色值。Range&#xff1a;范围属性&#xff0c;表示一个在…

基于微信小程序的校园二手交易平台小程序

文末联系获取源码 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏览器…

22讲MySQL有哪些“饮鸩止渴”提高性能的方法

短连接风暴 是指数据库有很多链接之后只执行了几个语句就断开的客户端&#xff0c;然后我们知道数据库客户端和数据库每次连接不仅需要tcp的三次握手&#xff0c;而且还有mysql的鉴权操作都要占用很多服务器的资源。话虽如此但是如果连接的不多的话其实这点资源无所谓的。 但是…

Web自动化——前端基础知识(二)

1. Web前端开发三要素 web前端开发三要素 什么是HTMl&#xff1f; Html是超文本标记语言&#xff0c;是用来描述网页的一种标记语言HTML是一种标签规则的形式将内容呈现在浏览器中可以以任意编辑器创建&#xff0c;其文件扩展名为.html或.htm保存即可 什么是CSS&#xff1f;…

ElasticSearch-第五天

目录 es中脑裂问题 脑裂定义 脑裂过程分析 解决方案 数据建模 前言 nested object 父子关系数据建模 父子关系 设置 Mapping 索引父文档 索引子文档 Parent / Child 所支持的查询 使用 has_child 查询 使用 has_parent 查询 使用 parent_id 查询 访问子文档 …

学习 Python 之 Pygame 开发魂斗罗(一)

学习 Python 之 Pygame 开发魂斗罗&#xff08;一&#xff09;Pygame回忆Pygame1. 使用pygame创建窗口2. 设置窗口背景颜色3. 获取窗口中的事件4. 在窗口中展示图片(1). pygame中的直角坐标系(2). 展示图片(3). 给部分区域设置颜色5. 在窗口中显示文字6. 播放音乐7. 图片翻转与…

人脸活体检测系统(Python+YOLOv5深度学习模型+清新界面)

摘要&#xff1a;人脸活体检测系统利用视觉方法检测人脸活体对象&#xff0c;区分常见虚假人脸&#xff0c;以便后续人脸识别&#xff0c;提供系统界面记录活体与虚假人脸检测结果。本文详细介绍基于YOLOv5深度学习技术的人脸活体检测系统&#xff0c;在介绍算法原理的同时&…

【C++】用手搓的红黑树手搓set和map

目录 一、set/map的底层结构 1、set/map的源码 2、利用模板区分set/map 3、利用仿函数控制比较大小 二、set/map的迭代器&#xff08;红黑树的迭代器&#xff09; 1、红黑树的begin、end迭代器 2、红黑树迭代器的operator 3、红黑树迭代器的operator-- 三、set的const…

人工智能大模型之ChatGPT原理解析

前言 近几个月ChatGPT爆火出圈&#xff0c;一路狂飙&#xff1b;它功能十分强大&#xff0c;不仅能回答各种各样的问题&#xff0c;还可以信写作&#xff0c;给程序找bug…我经过一段时间的深度使用后&#xff0c;十分汗颜&#xff0c;"智障对话"体验相比&#xff0c…

Spring-Data-Redis 和 Redisson TLS/SSL 连接

先决条件已经部署好redis tls环境。如未部署好&#xff0c;可参考&#xff1a;Redis 6.0 Docker容器使用SSL/TLS已知redis tls环境使用的证书&#xff1a;其中&#xff1a;ca.crt :服务器证书ca.key:服务器私钥redis.crt:客户端证书redis.key:客户端私钥证书处理生成证书p12文件…

Linux环境C语言开发基础

C语言是一门面向过程的计算机编程语言&#xff0c;与C、C#、Java等面向对象编程语言有所不同。C语言的设计目标是提供一种能以简易的方式编译、处理低级存储器、仅产生少量的机器码以及不需要任何运行环境支持便能运行的编程语言。C语言诞生于美国的贝尔实验室&#xff0c;由丹…

信创办公–基于WPS的PPT最佳实践系列(表格和图标常用动画)

信创办公–基于WPS的PPT最佳实践系列&#xff08;表格和图标常用动画&#xff09; 目录应用背景操作步骤图表常用动画效果&#xff1a;擦除效果表格常用动画效果&#xff1a;轮子效果应用背景 文不如表&#xff0c;表不如图。在平时用ppt做总结时&#xff0c;我们会经常用到图…