- 第 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;
}