当前位置: 首页 > article >正文

2025牛客寒假算法营2

A题

知识点:模拟

打卡。检查给定的七个整数是否仅包含 1,2,3,5,6 即可。为了便于书写,我们可以反过来,检查这七个整数是否不为 4 和 7。 时间 O(1);空间 O(1)。

 

#include <bits/stdc++.h>
using namespace std;

signed main() {
    bool flag = true;
    for (int i = 1; i <= 7; i++) {
        int x;
        cin >> x;
        if (x == 4 || x == 7) {
            flag = false;
        }
    }
    cout << (flag ? "YES" : "NO") << "\n";
}



B题

 

#include <bits/stdc++.h>
using namespace std;

signed main() {
    int n;
    cin >> n;
    vector<int> in(n + 1);
    for (int i = 1; i <= n; i++) {
        cin >> in[i];
    }
    sort(in.begin(), in.end());
    cout << in[n / 2 + 1] - 1 << "\n";
}



G题

 

#include <bits/stdc++.h>
using namespace std;

using i64 = long long;
const i64 inf = 1e18;

signed main() {
    int Task = 1;
    for (cin >> Task; Task; Task--) {
        int n, m;
        cin >> n >> m;
        i64 Min = 1e18, ans, now = 1;
        for (int i = 1; i <= 32; i++) {
            if (now >= inf / m) break;
            now *= m;
            if (abs(n - now) < Min) {
                Min = abs(n - now);
                ans = i;
            }
        }
        cout << ans << '\n';
    }
}



F题

 

#include <bits/stdc++.h>
using namespace std;

using i64 = long long;
 
signed main() {
    int Task = 1;
    for (cin >> Task; Task; Task--) {
        i64 l, r;
        cin >> l >> r;
        cout << (r - l + 1) << "\n";
    }
}

 




J题

 

 

#include <bits/stdc++.h>
using namespace std;

signed main() {
    int n, h, m;
    cin >> n >> h >> m;
    
    string Date = to_string(h) + "-";
    if (m < 10) {
        Date += "0" + to_string(m);
    }else {
        Date += to_string(m);
    }
    
    set<string> A, B, C;
    while (n--) {
        string user, date, time;
        cin >> user >> date >> time;
        
        if (date.substr(0, 7) != Date) {
            continue;
        }
        string h = time.substr(0, 2);
        if (h == "07" || h == "08" || time == "09:00:00" ||
            h == "18" || h == "19" || time == "20:00:00") {
            A.insert(user);
        }
        if (h == "11" || h == "12" || time == "13:00:00") {
            B.insert(user);
        }
        if (h == "22" || h == "23" || h == "00" || time == "01:00:00") {
            C.insert(user);
        }
    }
    cout << A.size() << " " << B.size() << " " << C.size() << "\n";
}



D题

 

 

#include <bits/stdc++.h>
using namespace std;

signed main() {
    int n;
    string s;
    cin >> n >> s;
    s = "#" + s;
    
    int ans = 0;
    for (int ch = 0; ch < 26; ch++) {
        int pre = 0, net = 0;
        for (int i = 1; i <= n; i++) {
            if (s[i] - 'a' != ch) continue;
            if (pre != 0) {
                ans = max(ans, n - i + 1);
            }
            pre = i;
        }
        for (int i = n; i >= 1; i--) {
            if (s[i] - 'a' != ch) continue;
            if (net != 0) {
                ans = max(ans, i);
            }
            net = i;
        }
    }
    cout << (ans == 1 ? 0 : ans) << "\n";
}

代码的核心思路是针对每个小写字母,分别正向和反向遍历字符串,找出该字母至少出现两次时的最长连续子串长度,最后取所有字母对应的最长长度作为可爱度。不过要注意,此代码实现与题目要求的可爱度定义可能存在差异,因为它仅考虑了单个字母的情况,而没有对所有可能的子串和不连续子序列进行检查。

例子 1

5
ababa
  • 分析过程
    • 代码开始遍历每个小写字母。当 ch 为 'a' 时:
      • 正向遍历
        • 第一次遇到 'a' 在位置 1,此时 pre 从 0 变为 1
        • 第二次遇到 'a' 在位置 3,此时 pre 不为 0,计算 n - i + 1 = 5 - 3 + 1 = 3,更新 ans 为 3
        • 第三次遇到 'a' 在位置 5,计算 n - i + 1 = 5 - 5 + 1 = 1ans 保持为 3
      • 反向遍历
        • 第一次遇到 'a' 在位置 5net 从 0 变为 5
        • 第二次遇到 'a' 在位置 3,此时 net 不为 0,计算 i = 3ans 保持为 3
        • 第三次遇到 'a' 在位置 1,计算 i = 1ans 保持为 3
    • 当 ch 为 'b' 时:
      • 正向遍历
        • 第一次遇到 'b' 在位置 2pre 从 0 变为 2
        • 第二次遇到 'b' 在位置 4,此时 pre 不为 0,计算 n - i + 1 = 5 - 4 + 1 = 2ans 保持为 3
      • 反向遍历
        • 第一次遇到 'b' 在位置 4net 从 0 变为 4
        • 第二次遇到 'b' 在位置 2,此时 net 不为 0,计算 i = 2ans 保持为 3
    • 最终 ans 为 3,输出结果为 3

例子 2

3
abc
  • 分析过程
    • 当 ch 为 'a' 时:
      • 正向遍历:只在位置 1 遇到 'a'pre 变为 1,但由于只出现一次,不会更新 ans
      • 反向遍历:同理,也不会更新 ans
    • 当 ch 为 'b' 时:
      • 正向遍历:只在位置 2 遇到 'b',不会更新 ans
      • 反向遍历:不会更新 ans
    • 当 ch 为 'c' 时:
      • 正向遍历:只在位置 3 遇到 'c',不会更新 ans
      • 反向遍历:不会更新 ans
    • 对于其他字母也都只出现一次。最终 ans 为 0,输出结果为 0

例子 3

4
aaaa
  • 分析过程
    • 当 ch 为 'a' 时:
      • 正向遍历
        • 第一次遇到 'a' 在位置 1pre 变为 1
        • 第二次遇到 'a' 在位置 2,此时 pre 不为 0,计算 n - i + 1 = 4 - 2 + 1 = 3,更新 ans 为 3
        • 第三次遇到 'a' 在位置 3,计算 n - i + 1 = 4 - 3 + 1 = 2ans 保持为 3
        • 第四次遇到 'a' 在位置 4,计算 n - i + 1 = 4 - 4 + 1 = 1ans 保持为 3
      • 反向遍历
        • 第一次遇到 'a' 在位置 4net 变为 4
        • 第二次遇到 'a' 在位置 3,此时 net 不为 0,计算 i = 3ans 保持为 3
        • 第三次遇到 'a' 在位置 2,计算 i = 2ans 保持为 3
        • 第四次遇到 'a' 在位置 1,计算 i = 1ans 保持为 3
    • 对于其他字母都未出现。最终 ans 为 3,输出结果为 3



K题

 

#include <bits/stdc++.h>
using namespace std;
// 定义长整型别名,在某些涉及较大整数运算时可使用
#define i64 long long
// 定义上下左右四个方向在 x 轴上的偏移量
int dx[4] = {-1, 1, 0, 0};
// 定义上下左右四个方向在 y 轴上的偏移量
int dy[4] = {0, 0, -1, 1};

// 解决问题的核心函数
void solve() {
    int n, m;
    // 读取矩阵的行数 n 和列数 m
    cin >> n >> m;
    // 定义一个字符串向量 s 来存储矩阵,索引从 1 开始,方便后续处理
    vector<string> s(n + 1);
    for (int i = 1; i <= n; i++) {
        // 读取每一行的字符串
        cin >> s[i];
        // 在每行字符串前添加一个字符 '%',使得字符串索引从 1 开始
        s[i] = "%" + s[i];
    }

    // 用于存储每个蓝色极大连通块对应的需要敲碎的灰色砖块数量,初始大小为 m * n + 1
    vector<int> g(m * n + 1);
    // 记录当前蓝色极大连通块的编号
    int idx = 0;
    // 二维布尔数组 v,用于标记矩阵中每个位置是否已被访问过
    vector<vector<bool>> v(n + 1, vector<bool>(m + 1, false));
    // 二维数组 num,记录每个蓝色砖块所属的蓝色极大连通块编号
    vector<vector<int>> num(n + 1, vector<int>(m + 1, 0));

    // 定义一个递归的 lambda 函数 dfs,用于深度优先搜索蓝色极大连通块
    auto dfs = [&](auto &&self, int x, int y, int id) -> void {
        // 标记当前位置 (x, y) 的蓝色砖块属于编号为 id 的连通块
        num[x][y] = id;
        // 标记当前位置已被访问
        v[x][y] = true;
        for (int i = 0; i < 4; i++) {
            // 计算相邻位置的 x 坐标
            int nx = dx[i] + x;
            // 计算相邻位置的 y 坐标
            int ny = dy[i] + y;
            // 检查相邻位置是否在矩阵范围内、未被访问且为蓝色砖块
            if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && !v[nx][ny] && s[nx][ny] == '1') {
                // 递归调用 dfs 函数继续搜索相邻的蓝色砖块
                self(self, nx, ny, id);
            }
        }
    };

    // 遍历矩阵中的每个位置
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            // 如果当前位置未被访问且为蓝色砖块
            if (!v[i][j] && s[i][j] == '1') {
                // 蓝色极大连通块编号加 1
                ++idx;
                // 调用 dfs 函数开始搜索该连通块
                dfs(dfs, i, j, idx);
            }
        }
    }

    // 再次遍历矩阵,统计每个蓝色极大连通块周围的灰色砖块数量
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (s[i][j] == '0') {
                // 用于记录当前灰色砖块相邻的不同蓝色极大连通块编号
                map<int, bool> ex;
                for (int k = 0; k < 4; k++) {
                    // 计算相邻位置的 x 坐标
                    int nx = i + dx[k];
                    // 计算相邻位置的 y 坐标
                    int ny = j + dy[k];
                    // 检查相邻位置是否在矩阵范围内、为蓝色砖块且该连通块编号未被记录过
                    if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && s[nx][ny] == '1' && !ex[num[nx][ny]]) {
                        // 对应连通块的需要敲碎的灰色砖块数量加 1
                        g[num[nx][ny]]++;
                        // 标记该连通块编号已被记录
                        ex[num[nx][ny]] = true;
                    }
                }
            }
        }
    }

    // 对存储每个连通块对应灰色砖块数量的向量 g 进行排序,排序范围是从索引 1 到 idx
    sort(g.begin() + 1, g.begin() + idx + 1);
    // 输出需要敲碎的最少灰色砖块数量
    cout << g[1];
}

int main() {
    // 关闭输入输出流的同步,提高输入输出效率
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int t = 1;
    // 循环调用 solve 函数,这里 t 为 1,即只调用一次
    while (t--) solve();
    return 0;
}

 


http://www.kler.cn/a/516216.html

相关文章:

  • 计算机网络 (57)改进“尽最大努力交付”的服务
  • leetcode 2920. 收集所有金币可获得的最大积分
  • css粘性定位超出指定宽度失效问题
  • 详细介绍:Kubernetes(K8s)的技术架构(核心概念、调度和资源管理、安全性、持续集成与持续部署、网络和服务发现)
  • Docker网段和服务器ip冲突导致无法访问网络的解决方法
  • 一文大白话讲清楚webpack基本使用——11——chunkIds和runtimeChunk
  • 如何理解Linux的根目录?与widows系统盘有何区别?
  • Ansys Motor-CAD:IPM 电机实验室 - 扭矩速度曲线
  • 独立站运营新突破:Clock斗篷技术助力商家降本增效
  • 使用 Tailwind CSS + PostCSS 实现响应式和可定制化的前端设计
  • python学opencv|读取图像(四十二)使用cv2.add()函数实现多图像叠加
  • cudatex文本编辑器
  • 备赛蓝桥杯之第十五届职业院校组省赛第一题:智能停车系统
  • go理论知识记录(入门)
  • 两台局域网电脑通过飞秋传输大文件失败的解决方案
  • python 统计相同像素值个数
  • 03垃圾回收篇(D4_彻底理解GC)
  • rust feature h和 workspace相关知识 (十一)
  • 【前端】Hexo 建站指南
  • 手机号码归属地与IP属地:两者差异深度解析
  • 图生3d算法学习笔记
  • 结构化布线系统分为六个子系统
  • MySQL 排序规则(COLLATE)详解
  • MySQL进阶之窗口函数
  • 从hello-web入手反混淆和disable_function绕过
  • 8.3 DALL·E 3:AI 文生图的颠覆性革命,为你的灵感插上翅膀