Topic 1:悠悠的重组数组
比较简单的一个题,因为前两天写了快速幂算法,一直想着用进位 &1之类的处理偶数,其实就正常用string装数字遍历%2就行了
#include <bits/stdc++.h>
using namespace std;
int main()
{
int q; cin >> q; // 读取查询次数
while(q--)
{
string s; cin >> s; // 输入一个字符串表示的数字
// 如果最后一位已经是偶数,不用改,直接输出原字符串
if((s.back() - '0') % 2 == 0)
{
cout << s << endl;
continue;
}
int pos = -1; // 记录可以交换的偶数位置
for(int i = 0; i < s.size(); ++i)
{
if((s[i] - '0') % 2 == 0) // 找到一个偶数
{
pos = i; // 记录该偶数的位置
swap(s[i], s.back());
break;// 交换第一个偶数和最后一位,直接完成结束了
}
}
// 如果找到了偶数,输出交换后的字符串;否则输出 -1
cout << (pos == -1 ? "-1" : s) << endl;
}
return 0;
}
Topic 2:体操队形
DFS递归+剪枝解决
稍微推理一下决策树,确定好剪枝条件
#include <bits/stdc++.h>
using namespace std;
int n, res = 0; // n: 队员数量,res: 方案数
vector<int> a; // a[i] 表示第 i 个人要求站在 a[i] 前面
vector<bool> vis; // vis[i] 表示第 i 个人是否已经安排[true:未安排]
// 深度优先搜索,尝试从位置 pos 开始安排队员
void dfs(int pos)
{
// 如果所有队员都已安排,说明找到一个合法的队形
if (pos > n)
{
++res;
return;
}
// 遍历每个队员,尝试安排
for (int i = 1; i <= n; ++i)
{
if (!vis[i] || (!vis[a[i]] && a[i])) continue; // 如果 i 已经安排,或者 i 不能站在 a[i] 前面,则跳过
vis[i] = false; // 安排队员 i,并标识为已安排
dfs(pos + 1); // 继续递归安排下一个位置
vis[i] = true; // 回溯:解放所有
}
}
int main() {
cin >> n; // 输入队员数量
a.resize(n + 1); // 调整数组大小,1到n使用 resize是调整大小
vis.assign(n + 1, true); // 初始化所有队员都未安排 assign是调整大小加改写数据
for (int i = 1; i <= n; ++i) cin >> a[i]; // 输入每个队员的要求
dfs(1); // 从位置 1 开始递归安排队员
cout << res << '\n'; // 输出合法的队形数量
return 0;
}
这题做的还不是特别懂,之后有时间得复习
Topic 3:二叉树的最大路径和
DFS递归 + 一点树形dp的思路
// 解决方案类 这破题的默认格式又是错的,要求你用main来自写输入
class Solution
{
public:
int maxSum = INT_MIN;
int dfs(TreeNode* node)
{
if (!node) return 0;
int leftGain = max(dfs(node->left), 0);
int rightGain = max(dfs(node->right), 0);
int priceNewPath = node->val + leftGain + rightGain;
maxSum = max(maxSum, priceNewPath);
return node->val + max(leftGain, rightGain);
}
int maxPathSum(TreeNode* root)
{
dfs(root);
return maxSum;
}
};
完整版贴出来,如果要自写main版本有个参照
#include <iostream>
#include <vector>
#include <queue>
#include <sstream>
#include <string>
#include <climits>
#include <algorithm>
using namespace std;
// 二叉树节点定义
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
// 构建树函数:从 "{1,2,3}" 或 "{-20,8,20,#,#,15,6}" 字符串构建二叉树
TreeNode* buildTree(const string& data) {
if (data.empty()) return nullptr;
string s = data;
s.erase(remove(s.begin(), s.end(), '{'), s.end());
s.erase(remove(s.begin(), s.end(), '}'), s.end());
stringstream ss(s);
string token;
vector<string> nodes;
while (getline(ss, token, ',')) {
nodes.push_back(token);
}
if (nodes.empty() || nodes[0] == "#") return nullptr;
TreeNode* root = new TreeNode(stoi(nodes[0]));
queue<TreeNode*> q;
q.push(root);
int i = 1;
while (!q.empty() && i < nodes.size()) {
TreeNode* curr = q.front();
q.pop();
if (i < nodes.size() && nodes[i] != "#") {
curr->left = new TreeNode(stoi(nodes[i]));
q.push(curr->left);
}
i++;
if (i < nodes.size() && nodes[i] != "#") {
curr->right = new TreeNode(stoi(nodes[i]));
q.push(curr->right);
}
i++;
}
return root;
}
// 解决方案类
class Solution {
public:
int maxSum = INT_MIN;
int dfs(TreeNode* node) {
if (!node) return 0;
int leftGain = max(dfs(node->left), 0);
int rightGain = max(dfs(node->right), 0);
int priceNewPath = node->val + leftGain + rightGain;
maxSum = max(maxSum, priceNewPath);
return node->val + max(leftGain, rightGain);
}
int maxPathSum(TreeNode* root) {
dfs(root);
return maxSum;
}
};
int main() {
string input;
getline(cin, input); // 输入如:{1,2,3}
TreeNode* root = buildTree(input);
Solution sol;
cout << sol.maxPathSum(root) << endl;
return 0;
}