【算法打卡day30(2026-03-23 周一)】BFSDFS孤岛题型-复习 & 第15届蓝桥杯省赛B组C++

- 第 196 篇 -
Date: 2026 - 03- 23 | 周一
Author: 郑龙浩(仟墨)
DFSBFS孤岛问题 & 第15届蓝桥杯省赛B组C++

文章目录

2026-03-22-23-算法打卡day30-BFSDFS孤岛题型-复习

三天没发博客了,前几天一直在忙一个计划书的项目,今天没有做那个

记得 2026-03-21日那天,也就是前天,我用两个小时做了蓝桥云课官方的第16届B组蓝桥杯(去年)C/C++组的题目,给我做吐了,前几个都是数学题,不怎么会,然后后面的题,因为BFS和DFS有一阵子没练了,然后就做了2个小时,也没怎么做完,反正也不想做了

因为21号是第29天打卡,那天又要忙不止一个计划书,又要刷真题,搞得我心态有点崩,刷题也没刷好,那天做题做的很烂,就不想发了

今天先将之前练习的矩阵类型的DFS和BFS练习了一下,找回题感

然后又去做了第15届B组蓝桥杯(前年)C/C++组的题目,这是我第二次正经做真题,给我做高兴了,虽然和大神比起来还是差很远,但是分数比我预估的要高

孤岛问题的代码都是正确的,

但是蓝桥杯的代码有的不怎么对,太晚了,也不改了,明天再看看具体哪里做错了,然后做出修正

明天把第14届的真题给练了,看看能得多少分吧

1-卡码网99-计数孤岛

cpp 复制代码
/* 2026-03-22-算法打卡day30-BFSDFS孤岛题型-复习
 * 1-卡码网99-计数孤岛
 * 算法:
 * Author:郑龙浩
 * Date:2026-03-22
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const ll N = 10000;
int direction[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
void dfs(vector <vector <int>>& grid, vector <vector<bool>>& visited, int x, int y) {
    int height = grid.size();
    int width = grid[0].size();
    visited[x][y] = true; // 传进来的都是没访问过的 & 都是陆地
    for (int i = 0; i < 4; i++) {
        int nextX = direction[i][0] + x;
        int nextY = direction[i][1] + y;
        if (nextX >= 0 && nextX < height && nextY >= 0 && nextY < width && grid[nextX][nextY] == 1 && visited[nextX][nextY] == false) {
            dfs(grid, visited, nextX, nextY);
        }
    }
}
void bfs(vector <vector <int>>& grid, vector <vector<bool>>& visited, int x, int y) {
    int height = grid.size();
    int width = grid[0].size();
    queue <pair <int, int>> que;
    que.push({x, y});
    visited[x][y] = true;
    // 最外层while作用主要是不段搜索「某周围还没有访问的坐标」,而内层for和if的作用才是「搜索周围坐标」
    while (!que.empty()) { // 只要还有周围没搜索的陆地,就继续
        int curX = que.front().first;
        int curY = que.front().second;
        que.pop();
        for (int i = 0; i < 4; i++) { // 对当前位置四周搜索
            int nextX = curX + direction[i][0];
            int nextY = curY + direction[i][1];
            // 如果没越界 && 是陆地 && 没访问过
            if (nextX >= 0 && nextX < height && nextY >= 0 && nextY < width) {
                if (grid[nextX][nextY] == 1 && visited[nextX][nextY] == false) {
                    que.push({nextX, nextY});
                    visited[nextX][nextY] = true; // 提前标记,避免que中出现多个相同坐标
                }
            }
        }
    }
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector <vector <int>> grid(n, vector <int> (m, 0));
    vector <vector <bool>> visited(n, vector <bool> (m, 0));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            cin >> grid[i][j];
        }
    }
    int cnt = 0;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (grid[i][j] == 1 && visited[i][j] == false) {
                // dfs(grid, visited, i, j);
                bfs(grid, visited, i, j);
                cnt++;
            }    
        }
    }
    cout << cnt;
    return 0;
}

2-力扣网100-最大岛屿的面积

cpp 复制代码
/* 2026-03-22-23-算法打卡day30-BFSDFS孤岛题型-复习
 * 2-力扣网100-最大岛屿的面积
 * 算法:DFS BFS
 * Author:郑龙浩
 * Date:2026-03-22
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const ll N = 10000;
int cnt = 0;
int direction[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
void dfs(vector <vector <int>>& grid, vector <vector <bool>>& visited, int x, int y) {
    int height = grid.size();
    int width = grid[0].size();
    visited[x][y] = true;
    cnt++;
    for (int i = 0; i < 4; i ++) {
        int nextX = direction[i][0] + x;
        int nextY = direction[i][1] + y;
        if (nextX >= 0 && nextX < height && nextY >= 0 && nextY < width) {
            if (grid[nextX][nextY] == 1 && visited[nextX][nextY] == false)
                dfs(grid, visited, nextX, nextY);
        }
    }
}
void bfs1(vector <vector <int>>& grid, vector <vector <bool>>& visited, int x, int y) {
    int height = grid.size();
    int width = grid[0].size();
    queue <pair <int, int>> que; que.push({x, y});
    visited[x][y] = true;
    cnt++;
    while (!que.empty()) {
        int curX = que.front().first;
        int curY = que.front().second;
        que.pop();
        for (int i = 0; i < 4; i++) {
            int nextX = direction[i][0] + curX;
            int nextY = direction[i][1] + curY;
            if (nextX >= 0 && nextX < height && nextY >= 0 && nextY < width) {
                if (grid[nextX][nextY] == 1 && visited[nextX][nextY] == false) {
                    que.push({nextX, nextY});
                    visited[nextX][nextY] = true;
                    cnt++;
                }
            }
        }
    }
}
// cnt++ 的位置可以换,上一个版本是在插入的时候就++,这一个版本那是在取出的时候cnt++,且这个要删掉在while前的cnt++,因为入循环取出que才++,所以不需要提前++
// 但也就仅限于cnt可以更换位置,但是,visited = true 不可以更换位置,否则会出现que中有多个相同坐标,这样标记的话,只要某坐标就直接标记了,
// 如果将标记写在push这里,就会出现,明明遇到过该左边,但就是因为没有标记,导致了误以为没有遇到过,就会push了很多个相同坐标
void bfs2(vector <vector <int>>& grid, vector <vector <bool>>& visited, int x, int y) {
    int height = grid.size();
    int width = grid[0].size();
    queue <pair <int, int>> que; que.push({x, y});
    visited[x][y] = true;
    cnt++;
    while (!que.empty()) {
        int curX = que.front().first;
        int curY = que.front().second;
        que.pop();
        for (int i = 0; i < 4; i++) {
            int nextX = direction[i][0] + curX;
            int nextY = direction[i][1] + curY;
            if (nextX >= 0 && nextX < height && nextY >= 0 && nextY < width) {
                if (grid[nextX][nextY] == 1 && visited[nextX][nextY] == false) {
                    que.push({nextX, nextY});
                    visited[nextX][nextY] = true;
                    cnt++;
                }
            }
        }
    }
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector <vector <int>> grid(n, vector <int> (m, 0));
    vector <vector <bool>> visited(n, vector <bool> (m, false));
    int Max = 0;
    for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) 
        cin >> grid[i][j];
    for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) {
        if (grid[i][j] == 1 && visited[i][j] == false) {
            cnt = 0;
            // dfs(grid, visited, i, j);
            // bfs1(grid, visited, i, j);
            bfs2(grid, visited, i, j);
            Max = max(Max, cnt);
        }
    }
    cout << Max;
    return 0;
}

3-卡码网101-孤岛的总面积

cpp 复制代码
/* 2026-03-22-23-算法打卡day30-BFSDFS孤岛题型-复习
 * 3-卡码网101-孤岛的总面积
 * 算法:DFS BFS
 * Author:郑龙浩
 * Date:2026-03-22
 * 之前写的一个版本是,将接触边缘变海洋,这次写的是将接触边缘的标记为访问过
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const ll N = 10000;
int cnt = 0;
int direction[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
void dfs(vector <vector <int>>& grid, vector <vector <bool>>& visited, int x, int y) {
    int height = grid.size();
    int width = grid[0].size();
    visited[x][y] = true;
    for (int i = 0; i < 4; i++) {
        int nextX = direction[i][0] + x;
        int nextY = direction[i][1] + y;
        if (nextX >= 0 && nextX < height && nextY >= 0 && nextY < width && grid[nextX][nextY] == 1 && visited[nextX][nextY] == false) {
            dfs(grid, visited, nextX, nextY);
        }
    }
}
void bfs(vector <vector <int>>& grid, vector <vector <bool>>& visited, int x, int y) {
    int height = grid.size();
    int width = grid[0].size();
    queue <pair <int, int>> que;
    que.push({x, y});
    visited[x][y] = true;
    while (!que.empty()) {
        int curX = que.front().first;
        int curY = que.front().second;
        que.pop();
        for (int i = 0; i < 4; i++) {
            int nextX = direction[i][0] + curX;
            int nextY = direction[i][1] + curY;
            if (nextX >= 0 && nextX < height && nextY >= 0 && nextY < width && grid[nextX][nextY] == 1 && visited[nextX][nextY] == false) {
                que.push({nextX, nextY});
                visited[nextX][nextY] = true;
            }
        }
    }
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector <vector <int>> grid(n, vector <int> (m, 0));
    vector <vector <bool>> visited(n, vector <bool> (m, false));
    int Max = 0;
    for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) 
        cin >> grid[i][j];
    // 首先将所有接触边缘的岛屿都先标记为访问过 / 都变为海洋
    for (int i = 0; i < n; i++) {
        if (grid[i][0] == 1 && visited[i][0] == false) bfs(grid, visited, i, 0); // dfs(grid, visited, i, 0); 
        if (grid[i][m - 1] == 1 && visited[i][m - 1] == false) bfs(grid, visited, i, m - 1); // dfs(grid, visited, i, m - 1);
    }
    for (int j = 0; j < m; j++) {
        if (grid[0][j] == 1 && visited[0][j] == false) bfs(grid, visited, 0, j); // dfs(grid, visited, 0, j); 
        if (grid[n - 1][j] == 1 && visited[n - 1][j] == false) bfs(grid, visited, n - 1, j); // dfs(grid, visited, n - 1, j);
    }
    for (int i = 1; i < n - 1; i++) for (int j = 1; j < m - 1; j++) {
        if (grid[i][j] == 1 && visited[i][j] == false) {
            cnt++;
        }
            
    }
    cout << cnt;
    return 0;
}
cpp 复制代码
/* 2026-03-22-23-算法打卡day30-BFSDFS孤岛题型-复习
 * 4-卡码网102-沉没孤岛
 * 算法:DFS BFS
 * Author:郑龙浩
 * Date:2026-03-22
 * 不需要真的将中间的孤岛变为海洋,那样需要写两个版本的dfs,一个是将边缘岛屿标记为访问过的dfs,然后再一个是将中间岛屿变为海洋的dfs
 * 只需要将边缘岛屿标记为2,中间岛屿为1,海洋依然0,输出的时候根据标记输出即可
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const ll N = 10000;
int cnt = 0;
int direction[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
void dfs(vector <vector <int>>& grid, int x, int y) {
    int height = grid.size();
    int width = grid[0].size();
    grid[x][y] = 2;
    for (int i = 0; i < 4; i++) {
        int nextX = direction[i][0] + x;
        int nextY = direction[i][1] + y;
        if (nextX >= 0 && nextX < height && nextY >= 0 && nextY < width && grid[nextX][nextY] == 1) {
            dfs(grid, nextX, nextY);
        }
    }
}
void bfs(vector <vector <int>>& grid, int x, int y) {
    int height = grid.size();
    int width = grid[0].size();
    queue <pair <int, int>> que;
    que.push({x, y});
    grid[x][y] = 2;
    while (!que.empty()) {
        int curX = que.front().first;
        int curY = que.front().second;
        que.pop();
        for (int i = 0; i < 4; i++) {
            int nextX = direction[i][0] + curX;
            int nextY = direction[i][1] + curY;
            if (nextX >= 0 && nextX < height && nextY >= 0 && nextY < width && grid[nextX][nextY] == 1) {
                que.push({nextX, nextY});
                grid[nextX][nextY] = 2;
            }
        }
    }
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector <vector <int>> grid(n, vector <int> (m, 0));
    for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) 
        cin >> grid[i][j];
    // 首先将所有接触边缘的岛屿都先标记为访问过 / 都变为海洋
    for (int i = 0; i < n; i++) {
        if (grid[i][0] == 1)  dfs(grid, i, 0); // bfs(grid, i, 0);
        if (grid[i][m - 1] == 1) dfs(grid, i, m - 1); // bfs(grid, i, m - 1);
    }
    for (int j = 0; j < m; j++) {
        if (grid[0][j] == 1) dfs(grid, 0, j); // bfs(grid, 0, j); 
        if (grid[n - 1][j] == 1) dfs(grid, n - 1, j); // bfs(grid, n - 1, j);
    }
    for (auto i : grid) {
        for (int j : i) cout << (j == 2 ? 1 : 0) << ' ';
        cout << '\n';
    }
    return 0;
}

5-卡码网103-高山流水

cpp 复制代码
/* 2026-03-22-23-算法打卡day30-BFSDFS孤岛题型-复习
 * 5-卡码网103-高山流水
 * 算法:DFS BFS
 * Author:郑龙浩
 * Date:2026-03-23
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const ll N = 10000;
int cnt = 0;
int direction[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
void dfs(vector <vector <int>>& grid, vector <vector <bool>>& visited, int x, int y) {
    int height = grid.size();
    int width = grid[0].size();
    visited[x][y] = true;
    for (int i = 0; i < 4; i++) {
        int nextX = direction[i][0] + x;
        int nextY = direction[i][1] + y;
        if (nextX >= 0 && nextX < height && nextY >= 0 && nextY < width)
            if (grid[nextX][nextY] >= grid[x][y] && visited[nextX][nextY] == false) {
                dfs(grid, visited, nextX, nextY);
            }
    }
}
void bfs(vector <vector <int>>& grid, vector <vector <bool>>& visited, int x, int y) {
    int height = grid.size();
    int width = grid[0].size();
    queue <pair <int, int>> que;
    que.push({x, y});
    visited[x][y] = true; // 边界也要标记为访问
    while (!que.empty()) {
        // 取出当前坐标
        int curX = que.front().first;
        int curY = que.front().second;
        que.pop();
        // 找到周围可以流向的坐标
        for (int i = 0; i < 4; i++) {
            int nextX = direction[i][0] + curX;
            int nextY = direction[i][1] + curY;
            if (nextX >= 0 && nextX < height && nextY >= 0 && nextY < width) // 没越界
                if (grid[nextX][nextY] >= grid[curX][curY] && visited[nextX][nextY] == false) {// 可以向上 
                    que.push({nextX, nextY});
                    visited[nextX][nextY] = true;
                }
        }
    }
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector <vector <int>> grid(n, vector <int> (m, 0));
    vector <vector <bool>> visited_1(n, vector <bool> (m, 0));
    vector <vector <bool>> visited_2(n, vector <bool> (m, 0));
    for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) 
        cin >> grid[i][j];
    // 从第一边界逆向流上去的,标记在visited1,反之,标记在visited_2
    for (int j = 0; j < m; j++) {
        // dfs(grid, visited_1, 0, j); // 上边界 - 第一组边界
        // dfs(grid, visited_2, n - 1, j); // 上边界 - 第二组边界
        bfs(grid, visited_1, 0, j); // 上边界 - 第一组边界
        bfs(grid, visited_2, n - 1, j); // 上边界 - 第二组边界
    }
    for (int i = 0; i < n; i++) {
        // dfs(grid, visited_1, i, 0); // 左边界 - 第一组边界
        // dfs(grid, visited_2, i, m - 1); // 右边界 - 第二组边界
        bfs(grid, visited_1, i, 0); // 左边界 - 第一组边界
        bfs(grid, visited_2, i, m - 1); // 右边界 - 第二组边界
    }
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            if (visited_1[i][j] == true && visited_2[i][j] == true)
                cout << i << ' ' << j << '\n';
    return 0;
}

6-卡码网104-建造最大岛屿

cpp 复制代码
/* 2026-03-22-23-算法打卡day30-BFSDFS孤岛题型-复习
 * 6-卡码网104-建造最大岛屿
 * 算法:DFS BFS
 * Author:郑龙浩
 * Date:2026-03-23
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const ll N = 10000;
int cnt = 0;
int direction[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
// 作用:记号 & 计数
void dfs(vector <vector <int>>& grid, int x, int y, int mark) {
    int height = grid.size();
    int width = grid[0].size();
    grid[x][y] = mark;
    cnt++;
    for (int i = 0; i < 4; i++) {
        int nextX = direction[i][0] + x;
        int nextY = direction[i][1] + y;
        if (nextX >= 0 && nextX < height && nextY >= 0 && nextY < width) // 没越界
            if (grid[nextX][nextY] == 1) // 如果是1,意味着没标记过,也就是没访问过,直接访问即可
                dfs(grid, nextX, nextY, mark);
    }
}
void bfs(vector <vector <int>>& grid, int x, int y, int mark) {
    int height = grid.size();
    int width = grid[0].size();
    queue <pair <int, int>> que;
    que.push({x, y});

}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int n, m; cin >> n >> m;
    vector <vector <int>> grid(n, vector <int> (m, 0));
    vector <vector <bool>> visited_1(n, vector <bool> (m, 0));
    vector <vector <bool>> visited_2(n, vector <bool> (m, 0));
    for (int i = 0; i < n; i++) for (int j = 0; j < m; j++) 
        cin >> grid[i][j];
    
    unordered_map <int, int> markSum; // 存储不同编号岛屿的面积是多少
    int mark = 2;
    for (int i = 0; i < n; i++) for (int j = 0; j < m; j++)
            if (grid[i][j] == 1) {
                cnt = 0;
                dfs(grid, i, j, mark); // 将每个岛屿进行编号 & 面积
                markSum[mark] = cnt; mark++;
            }
    // int maxSum = 0; // 错误初始化
    // 另一情况:若全是陆地,则下面的代码不会执行,所以,最大应该初始化为随便一个岛屿的面积
    // 如果全是海洋,直接输出1
    if (markSum.empty()) {cout << 1; return 0;}
    // 如果全是陆地,直接输第一个岛屿面积,也就是标记为2的岛屿面积
    if (mark == 3) { // 如果mark走到了3,则意味着只标记了一个岛屿
        cout << markSum[2];
        return 0;
    }
    int maxSum = 0;
    
    for (int i = 0; i < n; i++) for (int j = 0; j < m; j++)
            if (grid[i][j] == 0) { // 如果遇到了海洋,就要算周围的面积
                unordered_set <int> visitedMark; // 存储填充的海洋周围访问过(已经算入面积)的岛屿编号
                int sum = 1; // 自己也要算一个面积的
                for (int x = 0; x < 4; x++) {
                    int nextX = direction[x][0] + i;
                    int nextY = direction[x][1] + j;
                    if (nextX < 0 || nextX >= n || nextY < 0 || nextY >= m) continue;
                    int nextMark = grid[nextX][nextY];
                    // 如果当前海洋的下一个位置是岛屿 & 没有算入面积过
                    if (nextMark > 1 && visitedMark.find(nextMark) == visitedMark.end()) {
                        visitedMark.insert(nextMark); // 计入过面积的岛屿要标记
                        sum += markSum[nextMark]; // 就将当前岛屿面积算在内
                    }
                }
                maxSum = max(maxSum, sum); // 将当前填补位置后的总面积,和之前填补位置最大的总面积做比较
            }
    cout << maxSum;
    return 0;
}

2026-03-23-算法打卡day30-第15届蓝桥杯省赛B组C++

1-握手问题

通过率100%

cpp 复制代码
/* 2026-03-23-算法打卡day30-第15届蓝桥杯省赛B组
 * 1-握手问题
 * Author:郑龙浩
 * Date:2026-03-23
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cout << 43 * 42 / 2 + 43 * 7;
    return 0;
}

2-小球反弹

通过率100%

这个题不会,没想到怎么做

cpp 复制代码
/* 2026-03-23-算法打卡day30-第15届蓝桥杯省赛B组
 * 2-小球反弹
 * Author:郑龙浩
 * Date:2026-03-23
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    
    return 0;
}

3-好数

通过率100%

cpp 复制代码
/* 2026-03-22-23-算法打卡day30-第15届蓝桥杯省赛B组
 * 3-好数
 * Author:郑龙浩
 * Date:2026-03-23
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
bool IS (ll n) {
    bool jiou = true; // 奇数位为奇数
    while (n) {
        if (n % 10 % 2 != jiou) return false;
        n /= 10;
        jiou = (jiou + 1) % 2;
    }
    return true;
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    ll N; cin >> N;
    ll cnt = 0, n;
    for (ll i = 1; i <= N; i++) {
        if (IS(i)) cnt++;
    }
    cout << cnt;
    return 0;
}

4-R格式

通过率55%

还不知道哪里除了问题,不过最可气的是,我交卷之前没检查,我刚开始的输出是从ans2.size()开始的,交完卷之后就纳闷了,我记得可以通过示例来着,怎么一个都不对,最后一看是因为忘记-1了,比赛的时候可不要出这种问题,但是改成ans2.size() - 1后依然只对了55%的案例,不知道哪里出错了,明天看看吧

cpp 复制代码
/* 2026-03-23-算法打卡day30-第15届蓝桥杯省赛B组
 * 4-R格式
 * Author:郑龙浩
 * Date:2026-03-23 高精度乘法
 */

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    // 思路,直接将小数默认为整数高精度 * 单精度去计算,最后只需要根据头小数位四舍五入输出整数
    ll n; cin >> n;
    string s; cin >> s;
    n = pow(2, n);
    int len = s.size();
    int pointIndex = s.find('.'); // 找到小数点的索引,小数点的索引就是整数数量,后面是小数数量
    int xiaoshuCnt = s.substr(pointIndex + 1).size();
    // cout << len << ' ' << xiaoshuCnt << '\n';
    
    vector <ll> nums(10000);
    vector <ll> ans(10000);
    // 将小数逆向存入nums
    int i2 = 0;
    for (int i = len - 1; i >= 0; i--) {
        if (s[i] != '.') nums[i2++] = s[i] - '0';
    }
    len = i2; // 数组长度
    for (int i = 0; i < len; i++) {
        ans[i] += nums[i] * n;
        ans[i + 1] = ans[i] / 10;
        ans[i] %= 10;
    }
    while (ans[len] > 0) {
        ans[len + 1] = ans[len] / 10;
        ans[len] %= 10;
        len++;
    }
    // for (int i = 0; i < len; i++) cout << ans[i]; cout << '\n';
    vector <char> ans2;
    if (xiaoshuCnt != 0) { // 如果小数位数不是0,就插入小数点
        // 从z整数开始插入
        ans[xiaoshuCnt] = (ans[xiaoshuCnt - 1] >= 5 ? ans[xiaoshuCnt] + 1 : ans[xiaoshuCnt]); // 四舍五入
        // 从整数位置开始
        for (int i = xiaoshuCnt; i < len; i++) {
            ans2.push_back(ans[i] + '0');
        }
    } else {
        for (int i = 0; i < len; i++) ans2.push_back(ans[i] + '0');
    }
    for (int i = ans2.size() - 1; i >= 0; i--) cout << ans2[i];
    return 0;
}

5-宝石组合

运行超时了,因为确实没想到好的 方法,只能暴力了

cpp 复制代码
/* 2026-03-23-算法打卡day30-第15届蓝桥杯省赛B组
 * 5-宝石组合
 * Author:郑龙浩
 * Date:2026-03-23 高精度乘法
 */

#include "bits/stdc++.h"
#include "numeric"
#include "algorithm"
using namespace std;
typedef long long ll;
ll S(ll a, ll b, ll c) {
    return a * b * c * ((double)lcm(a, lcm(b, c)) / (lcm(a, b) * lcm(a, c) * lcm(b, c)));
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int N; cin >> N;
    vector <ll> nums(N, 0);
    for (int i = 0; i < N; i++) cin >> nums[i];
    sort(nums.begin(), nums.end());
    vector <ll> Max(4, 0);
    // 没什么思路,直接暴力吧
    for (int i = 0; i < N; i++) for (int j = i + 1; j < N; j++) for (int k = j + 1; k < N; k++) {
        ll result = S(nums[i], nums[j], nums[k]);
        if (Max[0] < result) {
            Max[0] = result; Max[1] = nums[i]; Max[2] = nums[j]; Max[3] = nums[k];
        }
    }
    cout << Max[1] << ' ' << Max[2] << ' ' << Max[3];
    return 0;
}

6-数字接龙

通过率75%

cpp 复制代码
/* 2026-03-23-算法打卡day30-第15届蓝桥杯省赛B组
 * 6-数字接龙
 * Author:郑龙浩
 * Date:2026-03-23
 * 算法:DFS & 回溯
 */

#include "bits/stdc++.h"
#include "numeric"
#include "algorithm"
using namespace std;
typedef long long ll;
vector <vector <int>> results;
vector <int> path;
int direction[8][2] = {{-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}, {-1, -1}};
// cnt是已经遍历的坐标的数量,否则会出现到了终点,但是没有全都遍历到的情况
// 我刚开始就忘记判断是否全都遍历过了
void dfs(vector <vector <int>>& grid, vector <vector <bool>>& visited, int x, int y, int N, int K, int cnt) {
    if (x == N - 1 && y == N - 1 && cnt == N * N) {
        // cout << "检验";
        results.push_back(path);
        return;
    }
    int regert = (grid[x][y] + 1) % K; // 下一个数字是什么
    for (int i = 0; i < 8; i++) {
        int nextX = direction[i][0] + x;
        int nextY = direction[i][1] + y;
        if (nextX >= 0 && nextX < N && nextY >= 0 && nextY < N) // 防止越界
        if (regert == grid[nextX][nextY] && visited[nextX][nextY] == false) // 可以到下一个 && 没访问过
        // 也就是只要有nex方向的任何一个没有访问过,就表示走过去,不会出现交叉
        if (visited[nextX][y] == false || visited[x][nextY] == false) { // 还要判断路径是否交叉,如果交叉就不能走
            // cout << grid[nextX][nextY] << ' ';
            path.push_back(i);
            visited[nextX][nextY] = true;
            dfs(grid, visited, nextX, nextY, N, K, cnt + 1);
            path.pop_back();
            visited[nextX][nextY] = false;
        }
    }
    return;
}
bool camp(vector <int>& a, vector <int>& b) {
    int len = a.size();
    for (int i = 0; i < len; i++) {
        if (a[i] < b[i]) return true;
        else if (a[i] > b[i]) return false;
    }
    return false;
}
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int N, K; cin >> N >> K;
    vector <vector <int>> grid(N, vector <int> (N, 0));
    vector <vector <bool>> visited(N, vector <bool> (N, false));
    for (int i = 0; i < N; i++) for (int j = 0; j < N; j++) cin >> grid[i][j];
    visited[0][0] = true; // 我的dfs只搜索周围,不搜索当前位置,所以要手动搜索当前
    dfs(grid, visited, 0, 0, N, K, 1);
    if (results.size() == 0) {
        cout << -1;
        return 0;
    }

    sort(results.begin(), results.end(), camp);
    // // 检验
    // for (auto i : results) {
    //     for (int j : i) cout << j;
    //     cout << '\n';
    // }
    for (int i = 0; i < results[0].size(); i++) cout << results[0][i];
    return 0;
}

7-拔河

通过率0%

我一位暴力能对至少一个,想多了,一个都没对哈哈哈,可能本来也想多了

前面耗时太久了,我记得做这个题的时候就剩了二十来分钟了 还是半小时来着,记不清楚了

cpp 复制代码
/* 2026-03-23-算法打卡day30-第15届蓝桥杯省赛B组
 * 7-拔河
 * Author:郑龙浩
 * Date:2026-03-23
 */

#include "bits/stdc++.h"
#include "numeric"
#include "algorithm"
using namespace std;
typedef long long ll;
int main() {
    ios::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    int n; cin >> n;
    vector <int> nums(n, 0);
    cin >> nums[0];
    for (int i = 1; i < n; i++) {
        cin >> nums[i];
        nums[i] += nums[i - 1];
    }
    int Min = INT_MAX;
    for (int i = 0; i < n - 1; i++) {
        int first = nums[i];
        int second = nums[n - 1] - nums[i];
        Min = min(Min, abs(second - first));
    }
    cout << Min;
    return 0;
}
相关推荐
沉鱼.442 小时前
树的题目集
数据结构·算法
不染尘.2 小时前
拓扑排序算法
开发语言·数据结构·c++·算法·排序算法·广度优先·深度优先遍历
m0_518019482 小时前
高性能日志库C++实现
开发语言·c++·算法
UnicornDev2 小时前
从零开始的C++编程之旅——第六篇:数组与字符串——批量数据的存储与处理
java·开发语言·算法
liulilittle2 小时前
LINUX RING BUFFER TUN/TAP 2
linux·运维·服务器·开发语言·网络·c++
阿里嘎多哈基米2 小时前
速通Hot100-Day10——二叉树
算法·leetcode·二叉树·递归·平衡二叉树
chushiyunen2 小时前
BM25稀疏检索算法笔记
笔记·算法·c#
芸忻2 小时前
day 23 第七章 回溯算法part02代码随想录算法训练营71期
算法
qq_334903152 小时前
C++中的装饰器模式高级应用
开发语言·c++·算法