Coding Practice,48天强训(28)

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:体操队形

I-体操队形_牛客小白月赛40

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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值