题目一:小r的特质骰子
题目描述:
给定一个整数 n 和一个整数数组 a,判断是否可以将数组 a 划分为 n/2 个子集,使得每个子集的元素和相等。
解题思路:
计算总和: 首先计算数组 a 的所有元素之和 sum。 判断可分性: 如果 sum 不能被 n/2 整除,则无法划分为等和子集,直接返回 false。 使用哈希表记录频率: 使用 unordered_map 记录每个数字出现的次数。 寻找配对数字: 遍历数组 a,对于每个数字 num,计算需要配对的数字 complement = target_sum - num。如果 complement 存在于哈希表中且出现次数大于 0,则将 num 和 complement 的出现次数都减 1,表示它们被配对成功。如果找不到配对数字,则返回 false。 判断是否配对成功: 如果所有数字都能成功配对,则返回 true,否则返回 false。 代码分析: 时间复杂度: O(n),其中 n 为数组 a 的长度。 空间复杂度: O(n),主要取决于哈希表的大小。
```#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;
bool solution(int n, vector<int> a) {
int sum = 0;
for (int num : a) {
sum += num;
}
// 检查总和是否能被 n/2 整除
if (sum % (n / 2) != 0) {
return false;
}
int target_sum = sum / (n / 2);
unordered_map<int, int> count;
// 记录每个数字的出现次数
for (int num : a) {
count[num]++;
}
// 尝试找到配对的数字
for (int num : a) {
if (count[num] > 0) {
int complement = target_sum - num;
if (count[complement] > 0) {
count[num]--;
count[complement]--;
} else {
return false;
}
}
}
return true;
}
int main() {
cout << (solution(6, {1, 2, 3, 4, 2, 3}) == true) << endl;
cout << (solution(4, {2, 3, 2, 3}) == true) << endl;
cout << (solution(8, {5, 1, 2, 3, 5, 1, 2, 3}) == false) << endl;
return 0;
}
```js
AI刷题思路:
思考如何高效存储和处理数据: 可以考虑使用其他数据结构,例如二叉搜索树或平衡树,来优化查找配对数字的效率。 尝试其他划分方法: 可以考虑使用贪心算法或其他方法,尝试将数组划分为等和子集。
题目二:小s的‘01’字符串
题目描述:
给定一个只包含字符 '0'、'1' 和 '?' 的字符串 s,计算将 '?' 替换为 '0' 或 '1' 后,所有可能的字符串中,相邻字符不相同的字符串数量。
解题思路:
定义函数 f(s): 该函数计算字符串 s 中相邻字符不相同的字符对数量。 使用广度优先搜索 (BFS): 使用队列 q 存储所有待处理的字符串。初始时,将输入字符串 s 加入队列。 处理字符串: 如果字符串 s 中不包含 '?',则直接计算 f(s) 并累加到结果 ans 中。 如果字符串 s 中包含 '?',则尝试将 '?' 替换为 '0' 和 '1',并将新的字符串加入队列。 返回结果: 返回 ans % mod,其中 mod 为一个给定的模数。 代码分析: 时间复杂度: O(2^n),其中 n 为字符串 s 的长度。这是因为需要枚举所有可能的 '?' 替换方案。 空间复杂度: O(2^n),主要取决于队列的大小。
AI刷题思路:
考虑剪枝: 可以考虑使用剪枝技术,避免处理一些不可能产生合法字符串的替换方案。 优化 BFS: 可以考虑使用其他搜索算法,例如深度优先搜索 (DFS) 或迭代加深搜索 (IDS),来优化搜索效率。 动态规划: 可以考虑使用动态规划方法,将问题分解为更小的子问题,并利用子问题的解来构造最终解。 总结 这两段代码分别解决了一个划分问题和字符串问题,展示了不同的解题思路和算法技巧。通过分析代码和思考 AI 刷题思路,我们可以更好地理解问题,并学习如何更有效地解决问题。
```#include <bits/stdc++.h>
#include <string>
#define mod 1000000007
using namespace std;
int f(const string& s) {
int cnt = 0;
for (int i = 1; s[i]; i++) {
if (s[i] != s[i - 1])cnt++;
}
return cnt;
}
int solution(const string& s) {
queue<string>q;
q.push(s);
int ans = 0;
while (!q.empty()) {
string cur = q.front();
q.pop();
if (cur.find('?') == string::npos) {
ans+=f(cur)%mod;
}
else {
string t1=cur,t2=cur;
for (int i = 0; cur[i]; i++) {
if (cur[i] == '?') {
t1[i] = '0';
t2[i] = '1';
q.push(t1);
q.push(t2);
break;
}
}
}
}
return ans%mod;
}
int main() {
cout << (solution("01?") == 3) << endl;
cout << (solution("1??0") == 6) << endl;
cout << (solution("?") == 0) << endl;
return 0;
}
```js