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

代码学习总结(二)

代码学习总结(二)

这个系列的博客是记录下自己学习代码的历程,有来自平台上的,有来自笔试题回忆的,主要基于 C++ 语言,包括题目内容,代码实现,思路,并会注明题目难度,保证代码运行结果

1 质数密钥

简单 质数密钥 组合与匹配

第一行输入两个正整数 n n n , m m m ( l ≤ n ≤ 20 l ≤n≤ 20 ln20 ; 1 ≤ m ≤ 14 1≤ m ≤ 14 1m14 )代表片段数量、片段长度。此后 n n n 行,第 i i i 行输入一个长度为 m m m ,仅由字符’0’和’1’组成的字符串 S S S ;表示第 i i i 个片段。

我们截获了 n n n 条片段,每一个片段均由 m m m 个字符组成,字符为’0’或者’1’。

你可以选择一些片段,将它们做按位或运算后,生成一个完整的密钥。根据加密算法的需求,合成后的密钥在转换为十进制的数值后必须恰好为一个质数,才能符合安全系统的运算要求(质数在许多公钥密码体系中具有特殊意义)。
请你设计一个程序,帮助安全专家确定:

任意选取片段,能得到多少个不同的质数密钥?

示例输入输出:
输入:m = 4, n = 4, {“0110”, “1110”, “1111”, “1011”}
输出:1

思路解析:

  1. 首先把二进制的字符片段转化为数字,以便于判断
  2. 之后对所有可能的组合进行搜索,在构造素数时,也采用记忆的模式,找到为素数的组合
  3. 返回最终的搜索存储后结果
is_prime函数
num < 2?
返回 false
初始化 i = 2
i <= sqrt'num'?
返回 true
num % i == 0?
i 加 1
开始
初始化 n 和 m 及 binary_strings
调用 count_prime_keys 函数
初始化 fragments 数组
初始化 i = 0
i < n?
初始化 prime_keys 集合
初始化 val = 0
遍历 binary_strings_i 中的字符 c
val = 'val << 1' or 'c - '0''
将 val 存入 fragments_i
i 加 1
初始化 mask = 1
mask < '1 << n'?
返回 prime_keys 的大小
初始化 key = 0
初始化 i = 0
i < n?
is_prime'key'?
mask & '1 << i'?
i 加 1
key 加入 fragments_i 中
mask 加 1
将 key 插入 prime_keys
输出结果
结束

本地 debug 代码

#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <cmath>
using namespace std;

// 判断一个数是否是质数
bool is_prime(int num) {
    if (num < 2) return false;
    for (int i = 2; i <= sqrt(num); ++i)
        if (num % i == 0)
            return false;
    return true;
}

// 核心逻辑函数:统计可以组合出的不同质数“钥匙”的个数
int count_prime_keys(int n, int m, const vector<string>& binary_strings) {
    vector<int> fragments(n);

    // 将二进制字符串转换为整数
    for (int i = 0; i < n; ++i) {
        int val = 0;
        for (char c : binary_strings[i]) {
            val = (val << 1) | (c - '0');
        }
        fragments[i] = val;
    }

    set<int> prime_keys;

    // 枚举所有非空子集并计算“钥匙”
    for (int mask = 1; mask < (1 << n); ++mask) {
        int key = 0;
        for (int i = 0; i < n; ++i) {
            if (mask & (1 << i)) {
                key |= fragments[i];
            }
        }
        if (is_prime(key)) {
            prime_keys.insert(key);
        }
    }

    return prime_keys.size();
}

int main() {
    int n, m;
    n = 4;
    m = 4;

    vector<string> binary_strings = {"0110", "1110", "1111", "1011"};

    int result = count_prime_keys(n, m, binary_strings);
    cout << result << endl;

    return 0;
}

上述代码的运行结果为

project cover 代码运行结果1

可用于提交的代码

// 判断一个数是否是质数
bool is_prime(int num) {
    if (num < 2) return false;
    for (int i = 2; i <= sqrt(num); ++i)
        if (num % i == 0)
            return false;
    return true;
}

// 核心逻辑函数:统计可以组合出的不同质数“钥匙”的个数
int count_prime_keys(int n, int m, const vector<string>& binary_strings) {
    vector<int> fragments(n);

    // 将二进制字符串转换为整数
    for (int i = 0; i < n; ++i) {
        int val = 0;
        for (char c : binary_strings[i]) {
            val = (val << 1) | (c - '0');
        }
        fragments[i] = val;
    }

    set<int> prime_keys;

    // 枚举所有非空子集并计算“钥匙”
    for (int mask = 1; mask < (1 << n); ++mask) {
        int key = 0;
        for (int i = 0; i < n; ++i) {
            if (mask & (1 << i)) {
                key |= fragments[i];
            }
        }
        if (is_prime(key)) {
            prime_keys.insert(key);
        }
    }

    return prime_keys.size();
}

2 N 矩阵

中等 字典树 单词拆分

对于给定的 n n n m m m 列的矩阵,每一个位置要么是大写字母’N’要么是大写字母’Z’
现在,你需要选择一整行和一整列(即选中一个"十"字形区域),将这个区域中的全部大写字母’Z替换为’N’,使得替换后的矩阵中,"N"的数量尽可能多。
直接输出这个最大数量。

注意:词典中的同一个单词可能在分段中被重复使用多次。

示例输入输出:
输入: n = 2; m = 2; {“NN”, “ZZ”}
输出: 2

思路解析:

  1. 在拿到矩阵时,首先可以先检查每行每列中 N 的数量
  2. 然后就是枚举搜索每个交叉点的N的数量了
  3. N 的数量最多的,就是答案
graph TD
    classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
    classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px

    A([开始]):::startend --> B(初始化 n、m 和 matrix):::process
    B --> C(调用 getMaxNCountAfterReplacement 函数):::process
    C --> D(初始化 rowNCount 数组,大小为 n,初始值为 0):::process
    D --> E(初始化 colNCount 数组,大小为 m,初始值为 0):::process
    E --> F(初始化 totalN = 0):::process
    F --> G(初始化 i = 0):::process
    G --> H{i < n?}:::decision
    H -->|否| I(初始化 maxTotalN = 0):::process
    H -->|是| J(初始化 j = 0):::process
    J --> K{j < m?}:::decision
    K -->|否| L(i 加 1):::process
    K -->|是| M{matrix_i_j == 'N'?}:::decision
    M -->|否| N(j 加 1):::process
    M -->|是| O(rowNCount'i' 加 1):::process
    O --> P(colNCount'j' 加 1):::process
    P --> Q(totalN 加 1):::process
    Q --> N
    N --> K
    L --> H
    I --> R(初始化 r = 0):::process
    R --> S{r < n?}:::decision
    S -->|否| T(返回 maxTotalN):::process
    S -->|是| U(初始化 c = 0):::process
    U --> V{c < m?}:::decision
    V -->|否| W(r 加 1):::process
    V -->|是| X(currentN = rowNCount'r' + colNCount'c'):::process
    X --> Y{matrix'r''c' == 'N'?}:::decision
    Y -->|否| Z(maxTotalN = max'maxTotalN, currentN'):::process
    Y -->|是| AA(currentN 减 1):::process
    AA --> Z
    Z --> AB(c 加 1):::process
    AB --> V
    W --> S
    T --> AC(输出结果):::process
    AC --> AD([结束]):::startend

本地 debug 代码

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

// 核心处理函数
int getMaxNCountAfterReplacement(int n, int m, const vector<string>& matrix) {
    vector<int> rowNCount(n, 0); // 每行N的数量
    vector<int> colNCount(m, 0); // 每列N的数量
    int totalN = 0;

    // 统计每行和每列的N数量
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (matrix[i][j] == 'N') {
                rowNCount[i]++;
                colNCount[j]++;
                totalN++;
            }
        }
    }

    int maxTotalN = 0;

    // 枚举每一个交叉点(行r和列c)
    for (int r = 0; r < n; ++r) {
        for (int c = 0; c < m; ++c) {
            int currentN = rowNCount[r] + colNCount[c];
            if (matrix[r][c] == 'N') {
                // 如果交叉点本身是'N',加了两次,要减一
                currentN -= 1;
            }
            maxTotalN = max(maxTotalN, currentN);
        }
    }

    return maxTotalN;
}

int main() {
    int n, m;
    n = 2; m = 2;
    vector<string> matrix{"NN", "ZZ"};

    int result = getMaxNCountAfterReplacement(n, m, matrix);
    cout << result << endl;

    return 0;
}

上述代码的运行结果为

project cover 代码运行结果2

可用于提交的代码

int getMaxNCountAfterReplacement(int n, int m, const vector<string>& matrix) {
    vector<int> rowNCount(n, 0); // 每行N的数量
    vector<int> colNCount(m, 0); // 每列N的数量
    int totalN = 0;

    // 统计每行和每列的N数量
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            if (matrix[i][j] == 'N') {
                rowNCount[i]++;
                colNCount[j]++;
                totalN++;
            }
        }
    }

    int maxTotalN = 0;

    // 枚举每一个交叉点(行r和列c)
    for (int r = 0; r < n; ++r) {
        for (int c = 0; c < m; ++c) {
            int currentN = rowNCount[r] + colNCount[c];
            if (matrix[r][c] == 'N') {
                // 如果交叉点本身是'N',加了两次,要减一
                currentN -= 1;
            }
            maxTotalN = max(maxTotalN, currentN);
        }
    }

    return maxTotalN;
}

这里的题目是 来自笔试中的回忆版本 ,感兴趣的同学们可以看看解题思路,每日二题,努力加油😉!!!

相关文章:

  • AIDD-人工智能药物-pyecharts-gallery
  • 滑动窗口(4)—将x减到0的最⼩操作数
  • 基于时间序列分解与XGBoost的交通通行时间预测方法解析
  • x265 编码参数 rdLevel 详细解析
  • buuctf sql注入类练习
  • UITableVIew性能优化概述
  • 【DE2-115】Verilog实现DDS+Quartus仿真波形
  • 【算法】One-Stage检测器与Two-Stage检测器的原理和区别
  • 开启bitlocker使用windows的加密功能
  • (1)VTK环境配置
  • Unity 基于navMesh的怪物追踪惯性系统
  • CAP理论 与 BASE理论
  • RAG文献阅读——用于知识密集型自然语言处理任务的检索增强生成
  • 数据库删除表数据
  • 在C盘新建文本文档
  • Go环境变量配置
  • Qt报错dependent ‘..\..\..\..\..\..\xxxx\QMainWindow‘ 或者 QtCore\QObject not exist
  • QEMU学习之路(7)— ARM64 启动Linux
  • 每天学一个 Linux 命令(16):mkdir
  • 【寻找Linux的奥秘】第四章:基础开发工具(下)
  • qq空间怎么做网站/国家卫健委最新疫情报告
  • 做哪个网站有效果/seo搜索引擎优化是通过优化答案
  • 网站底部图标代码/怎么样自己创建网站
  • wordpress 博客同步/站内优化
  • 东营市城市和建设管理局网站/推广有奖励的app平台
  • 南昌金启网站建设/关键词优化seo外包