杭州做肉松饼的网站有多少家淘宝店铺购买的服务在哪里
代码学习总结(二)
这个系列的博客是记录下自己学习代码的历程,有来自平台上的,有来自笔试题回忆的,主要基于 C++ 语言,包括题目内容,代码实现,思路,并会注明题目难度,保证代码运行结果
1 质数密钥
简单
质数密钥
组合与匹配
第一行输入两个正整数 n n n , m m m ( l ≤ n ≤ 20 l ≤n≤ 20 l≤n≤20 ; 1 ≤ m ≤ 14 1≤ m ≤ 14 1≤m≤14 )代表片段数量、片段长度。此后 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
思路解析:
- 首先把二进制的字符片段转化为数字,以便于判断
- 之后对所有可能的组合进行搜索,在构造素数时,也采用记忆的模式,找到为素数的组合
- 返回最终的搜索存储后结果
本地 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;
}
上述代码的运行结果为

可用于提交的代码
// 判断一个数是否是质数
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
思路解析:
- 在拿到矩阵时,首先可以先检查每行每列中 N 的数量
- 然后就是枚举搜索每个交叉点的N的数量了
- N 的数量最多的,就是答案
graph TDclassDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2pxclassDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2pxclassDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2pxA([开始]):::startend --> B(初始化 n、m 和 matrix):::processB --> C(调用 getMaxNCountAfterReplacement 函数):::processC --> D(初始化 rowNCount 数组,大小为 n,初始值为 0):::processD --> E(初始化 colNCount 数组,大小为 m,初始值为 0):::processE --> F(初始化 totalN = 0):::processF --> G(初始化 i = 0):::processG --> H{i < n?}:::decisionH -->|否| I(初始化 maxTotalN = 0):::processH -->|是| J(初始化 j = 0):::processJ --> K{j < m?}:::decisionK -->|否| L(i 加 1):::processK -->|是| M{matrix_i_j == 'N'?}:::decisionM -->|否| N(j 加 1):::processM -->|是| O(rowNCount'i' 加 1):::processO --> P(colNCount'j' 加 1):::processP --> Q(totalN 加 1):::processQ --> NN --> KL --> HI --> R(初始化 r = 0):::processR --> S{r < n?}:::decisionS -->|否| T(返回 maxTotalN):::processS -->|是| U(初始化 c = 0):::processU --> V{c < m?}:::decisionV -->|否| W(r 加 1):::processV -->|是| X(currentN = rowNCount'r' + colNCount'c'):::processX --> Y{matrix'r''c' == 'N'?}:::decisionY -->|否| Z(maxTotalN = max'maxTotalN, currentN'):::processY -->|是| AA(currentN 减 1):::processAA --> ZZ --> AB(c 加 1):::processAB --> VW --> ST --> AC(输出结果):::processAC --> 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;
}
上述代码的运行结果为

可用于提交的代码
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;
}
这里的题目是 来自笔试中的回忆版本 ,感兴趣的同学们可以看看解题思路,每日二题,努力加油😉!!!