树 形 DP (dnf序)

二叉搜索子树的最大键值
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:class info{public:int maxnum;int minnum;bool isbst;int sum;int maxbstsum;info(int a,int b,bool c,int d,int e){maxnum=a;minnum=b;isbst=c;sum=d;maxbstsum=e;}};info f(TreeNode* root){if(root==nullptr)return info(INT_MIN,INT_MAX,true,0,0);info infol=f(root->left);info infor=f(root->right);int maxn=max(root->val,max(infol.maxnum,infor.maxnum));int minn=min(root->val,min(infol.minnum,infor.minnum));int sumn=root->val+infol.sum+infor.sum;bool isbetn=infol.isbst&&infor.isbst&&root->val<infor.minnum&&root->val>infol.maxnum;int maxbetnumn=max(infol.maxbstsum,infor.maxbstsum);if(isbetn)maxbetnumn=max(maxbetnumn,sumn);return info(maxn,minn,isbetn,sumn,maxbetnumn);}int maxSumBST(TreeNode* root) {return f(root).maxbstsum;}
};
递归求从头节点向下的最大的最大子树键值和,而到一个头节点要求其最大的键值和:如果不选头节点,需要子树上的最大键值和;如果选头节点,需要知道子树是否为二叉搜索树和子树所有节点的和,并且还需要子树上的最大值和最小值和头节点比较判断是否可以选头节点。最后把所有需要的信息整合到一起传递给父节点
二叉树的直径
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),* right(right) {}* };*/
class Solution {
public:class info {public:int height;int diameter;info(int a, int b) {diameter = a;height = b;}};info f(TreeNode* cur) {if (cur == nullptr)return info(0, 0);info infol = f(cur->left);info infor = f(cur->right);int dia = max(infol.diameter, infor.diameter);dia = max(dia, infol.height + infor.height);int hei = max(infol.height, infor.height) + 1;return info(dia, hei);}int diameterOfBinaryTree(TreeNode* root) { return f(root).diameter; }
};
从一个头节点及其子树求最大的直径:如果不选头节点,需要其子树的最大直径和;如果选头节点,需要子树的高度
在二叉树中分配金币
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),* right(right) {}* };*/
class Solution {
public:int ans = 0;int f(TreeNode* root) {if (root == nullptr)return 0;int d = f(root->left) + f(root->right) + root->val - 1;ans += abs(d);return d;}int distributeCoins(TreeNode* root) {f(root);return ans;}
};
所有硬币的移动路径之和,是由每条边经过的次数累加和组成,所以只要求出每条边的经过次数求和即可。求一个子树所有边的经过次数之和,需要其子树的所有经过边之和,还有每个子树的节点与其子树上的硬币数量,做差的绝对值就是从头节点的子树到头节点之间的那条边经过的次数
没有上司的舞会
#include <iostream>
#include <vector>
using namespace std;
const int maxn = 6002;
int cnt;
int head[maxn];
int to[maxn];
int nex[maxn];
int happy[maxn];
bool laoda[maxn];
int yes[maxn];
int no[maxn];
void build(int n) {cnt = 1;for (int i = 1; i <= n; i++) {head[i] = 0;happy[i] = 0;laoda[i] = true;yes[i] = 0;no[i] = 0;}
}
void insert(int u, int v) {nex[cnt] = head[u];to[cnt] = v;head[u] = cnt++;
}void f(int cur) {no[cur] = 0;yes[cur] = happy[cur];for (int edge = head[cur]; edge > 0; edge = nex[edge]) {int v = to[edge];f(v);no[cur] += max(no[v], yes[v]);yes[cur] += no[v];}}
int main() {int n;cin >> n;build(n);for (int i = 1; i <= n; i++) {int a;cin >> a;happy[i] = a;}for (int i = 1; i < n; i++) {int a, b;cin >> a >> b;insert(b,a);laoda[a] = false;}int head;for (int i = 1; i <= n; i++)if (laoda[i] == true) {head = i;break;}f(head);cout << max(yes[head], no[head]);return 0;}
求一个树的最大快乐值:如果不选头节点,只需要其子树:选子树头节点的最大快乐值和不选子树头节点的最大快乐值;如果选头节点,需要不选子树头节点的最大快乐值
监控二叉树
public class Solution {// 提交如下的方法public int minCameraCover(TreeNode root) {ans = 0;if (f(root) == 0) {ans++;}return ans;}// 遍历过程中一旦需要放置相机,ans++public static int ans;// 递归含义// 假设x上方一定有父亲的情况下,这个假设很重要// x为头的整棵树,最终想都覆盖,// 并且想使用最少的摄像头,x应该是什么样的状态// 返回值含义// 0: x是无覆盖的状态,x下方的节点都已经被覆盖// 1: x是覆盖状态,x上没摄像头,x下方的节点都已经被覆盖// 2: x是覆盖状态,x上有摄像头,x下方的节点都已经被覆盖private int f(TreeNode x) {if (x == null) {return 1;}int left = f(x.left);int right = f(x.right);if (left == 0 || right == 0) {ans++;return 2;}if (left == 1 && right == 1) {return 0;}return 1;}}
一个节点的情况:1.没有被监控覆盖 2.被覆盖但没有放监控 3.被覆盖并且放了监控
根据不同的节点情况讨论即可
路径总和
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}* };*/
class Solution {
public:int ans;;unordered_map<long ,int>umap;void f(TreeNode* cur,long sum,int targetSum){if(cur==nullptr)return ;sum+=cur->val;long need=sum-targetSum;if(umap.find(need)!=nullptr) ans+=umap[need];umap[sum]++;f(cur->left,sum,targetSum);f(cur->right,sum,targetSum);umap[sum]--;}int pathSum(TreeNode* root, int targetSum) {umap.clear();ans=0;umap[0]=1;f(root,0,targetSum);return ans;}
};
树形dp不仅父亲节点需要子节点信息,也可以从父节点向子节点传递信息。求target的路径,如果知道之前遍历过的所有的节点之和,和之前所有从根节点到遍历过的节点的的路径和的路径个数,求出sum-target的路径个数累加即可
到达首都的最少耗油量
public class Solution {public static long minimumFuelCost(int[][] roads, int seats) {int n = roads.length + 1;ArrayList<ArrayList<Integer>> graph = new ArrayList<>();for (int i = 0; i < n; i++) {graph.add(new ArrayList<>());}for (int[] r : roads) {graph.get(r[0]).add(r[1]);graph.get(r[1]).add(r[0]);}int[] size = new int[n];long[] cost = new long[n];f(graph, seats, 0, -1, size, cost);return cost[0];}// 根据图,当前来到u,u的父节点是p// 遍历完成后,请填好size[u]、cost[u]public static void f(ArrayList<ArrayList<Integer>> graph, int seats, int u, int p, int[] size, long[] cost) {size[u] = 1;for (int v : graph.get(u)) {if (v != p) {f(graph, seats, v, u, size, cost);size[u] += size[v];cost[u] += cost[v];// a/b向上取整,可以写成(a+b-1)/b// (size[v]+seats-1) / seats = size[v] / seats 向上取整cost[u] += (size[v] + seats - 1) / seats;}}}}
求到达头节点a的最少油量,需要其子树的最少油量,还需要到达其子树的头节点的人的个数,人数对seats求上限加子树的油量就是到达a的最少油量
相邻字符不同的最长路径
class Solution {
public:vector<vector<int>> pragh;void build(int n) {for (int i = 0; i < n; i++)pragh.push_back(vector<int>());}void insert(int u, int v) { pragh[u].push_back(v); }class info {public:int maxhead;int maxleng;info(int a, int b) {maxhead = a;maxleng = b;}};info f(string& s, int cur) {if (pragh[cur].empty())return info(1, 1);int max1 = 0, max2 = 0;int maxheight = 0;for (int edge : pragh[cur]) {info rem = f(s, edge);maxheight = max(maxheight, rem.maxleng);if (s[cur] != s[edge]) {if (rem.maxhead > max1) {max2 = max1;max1 = rem.maxhead;} else if (rem.maxhead > max2) {max2 = rem.maxhead;}}}maxheight = max(maxheight, max1 + max2 + 1);int maxn = max1 + 1;return info(maxn, maxheight);}int longestPath(vector<int>& parent, string s) {int n = parent.size();build(n);for (int i = 1; i < n; i++) {insert(parent[i], i);}return f(s, 0).maxleng;}
};
求头节点a的子树的最大路径:如果不选a,需a的子树的最大路径和;如果选a,需要子树的头节点向下延申的最大长度

移除子树后的二叉树高度
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left),* right(right) {}* };*/
class Solution {
public:static const int maxn = 100005;int dfn[maxn];int size[maxn];int deep[maxn];int maxl[maxn];int maxr[maxn];int dfnnum;void f(TreeNode* cur, int k) {int i = ++dfnnum;dfn[cur->val] = i;deep[i] = k;size[i] = 1;if (cur->left != nullptr) {f(cur->left, k + 1);size[i] += size[dfn[cur->left->val]];}if (cur->right != nullptr) {f(cur->right, k + 1);size[i] += size[dfn[cur->right->val]];}}vector<int> treeQueries(TreeNode* root, vector<int>& queries) {dfnnum = 0;f(root, 0);for (int i = 1; i <= dfnnum; i++) {maxl[i] = max(maxl[i - 1], deep[i]);}maxl[0] = 0;maxl[dfnnum + 1] = 0;for (int i = dfnnum; i >= 1; i--)maxr[i] = max(maxr[i + 1], deep[i]);maxr[0] = 0;maxr[dfnnum + 1] = 0;int m = queries.size();vector<int> ans;for (int i = 0; i < m; i++) {int leftmax = maxl[dfn[queries[i]] - 1];int rightmax = maxr[dfn[queries[i]] + size[dfn[queries[i]]]];ans.push_back(max(leftmax, rightmax));}return ans;}
};
对树做dfn序,然后求个子树的大小和各节点的高度,并且求出从0到各dfn序节点之间的最大高度和从n到各dfn序节点的最大高度,然后挨个求就可以
从树中删除边的最小分数
class Solution {
public:static const int maxn = 1005;vector<vector<int>> pragh;int dfn[maxn];int size[maxn];int xog[maxn];int dfnnum;void build(int n) {int dfnnum = 0;for (int i = 0; i <= n; i++) {pragh.push_back(vector<int>());dfn[i] = 0;size[0] = 0;xog[i] = 0;}}void insert(int u, int v) {pragh[u].push_back(v);pragh[v].push_back(u);}void f(int cur, vector<int>& nums) {int i = ++dfnnum;dfn[cur] = i;xog[i] = nums[cur];size[i] = 1;for (auto node : pragh[cur]) {if (dfn[node] == 0) {f(node, nums);xog[i] ^= xog[dfn[node]];size[i] += size[dfn[node]];}}}int minimumScore(vector<int>& nums, vector<vector<int>>& edges) {int n = nums.size();build(n);for (auto edge : edges) {insert(edge[0], edge[1]);}f(0, nums);int ans = INT_MAX;for (int i = 0; i < edges.size(); i++) {int a = max(dfn[edges[i][0]], dfn[edges[i][1]]);for (int j = i + 1; j < edges.size(); j++) {int b = max(dfn[edges[j][0]], dfn[edges[j][1]]);int pre, pos;if (a < b) {pre = a;pos = b;} else {pre = b;pos = a;}int sum1 = xog[pos];int sum2, sum3;if (pre + size[pre] > pos) {sum2 = sum1 ^ xog[pre];sum3 = xog[pre] ^ xog[1];} else {sum2 = xog[pre];sum3 = sum1 ^ sum2 ^ xog[1];}ans = min(ans, max(sum1, max(sum2, sum3)) -min(sum1, min(sum2, sum3)));}}return ans;}
};
求出各子树的异或和,然后两次for循环枚举各边
选课
三维树形dp,枚举最右子树的分配节点个数讨论
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.ArrayList;// 普通解法,邻接表建图 + 相对好懂的动态规划
// 几乎所有题解都是普通解法的思路,只不过优化了常数时间、做了空间压缩
// 但时间复杂度依然是O(n * 每个节点的孩子平均数量 * m的平方)
public class Main {public static int MAXN = 301;public static int[] nums = new int[MAXN];public static ArrayList<ArrayList<Integer>> graph;static {graph = new ArrayList<>();for (int i = 0; i < MAXN; i++) {graph.add(new ArrayList<>());}}public static int[][][] dp = new int[MAXN][][];public static int n, m;public static void build(int n) {for (int i = 0; i <= n; i++) {graph.get(i).clear();}}public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));StreamTokenizer in = new StreamTokenizer(br);PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));while (in.nextToken() != StreamTokenizer.TT_EOF) {// 节点编号从0~nn = (int) in.nval;in.nextToken();m = (int) in.nval + 1;build(n);for (int i = 1, pre; i <= n; i++) {in.nextToken();pre = (int) in.nval;graph.get(pre).add(i);in.nextToken();nums[i] = (int) in.nval;}out.println(compute());}out.flush();out.close();br.close();}public static int compute() {for (int i = 0; i <= n; i++) {dp[i] = new int[graph.get(i).size() + 1][m + 1];}for (int i = 0; i <= n; i++) {for (int j = 0; j < dp[i].length; j++) {for (int k = 0; k <= m; k++) {dp[i][j][k] = -1;}}}return f(0, graph.get(0).size(), m);}// 当前来到i号节点为头的子树// 只在i号节点、及其i号节点下方的前j棵子树上挑选节点// 一共挑选k个节点,并且保证挑选的节点连成一片// 返回最大的累加和public static int f(int i, int j, int k) {if (k == 0) {return 0;}if (j == 0 || k == 1) {return nums[i];}if (dp[i][j][k] != -1) {return dp[i][j][k];}int ans = f(i, j - 1, k);// 第j棵子树头节点v int v = graph.get(i).get(j - 1);for (int s = 1; s < k; s++) {ans = Math.max(ans, f(i, j - 1, k - s) + f(v, graph.get(v).size(), s));}dp[i][j][k] = ans;return ans;}}
定义"最优子结构",从大的dfn序到小的dfn序推出转移方程
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;
public class Main {public static int MAXN = 301;public static int[] nums = new int[MAXN];// 链式前向星建图public static int edgeCnt;public static int[] head = new int[MAXN];public static int[] next = new int[MAXN];public static int[] to = new int[MAXN];// dfn的计数public static int dfnCnt;// 下标为dfn序号public static int[] val = new int[MAXN + 1];// 下标为dfn序号public static int[] size = new int[MAXN + 1];// 动态规划表public static int[][] dp = new int[MAXN + 2][MAXN];public static int n, m;public static void build(int n, int m) {edgeCnt = 1;dfnCnt = 0;Arrays.fill(head, 0, n + 1, 0);Arrays.fill(dp[n + 2], 0, m + 1, 0);}public static void addEdge(int u, int v) {next[edgeCnt] = head[u];to[edgeCnt] = v;head[u] = edgeCnt++;}public static void main(String[] args) throws IOException {BufferedReader br = new BufferedReader(new InputStreamReader(System.in));StreamTokenizer in = new StreamTokenizer(br);PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));while (in.nextToken() != StreamTokenizer.TT_EOF) {n = (int) in.nval;in.nextToken();m = (int) in.nval;build(n, m);for (int i = 1; i <= n; i++) {in.nextToken();addEdge((int) in.nval, i);in.nextToken();nums[i] = (int) in.nval;}out.println(compute());}out.flush();out.close();br.close();}public static int compute() {f(0);// 节点编号0 ~ n,dfn序号范围1 ~ n+1// 接下来的逻辑其实就是01背包!不过经历了很多转化// 整体的顺序是根据dfn序来进行的,从大的dfn序,遍历到小的dfn序// dp[i][j] : i ~ n+1 范围的节点,选择j个节点一定要形成有效结构的情况下,最大的累加和// 怎么定义有效结构?重点!重点!重点!// 假设i ~ n+1范围上,目前所有头节点的上方,有一个总的头节点// i ~ n+1范围所有节点,选出来j个节点的结构,// 挂在这个假想的总头节点之下,是一个连续的结构,没有断开的情况// 那么就说,i ~ n+1范围所有节点,选出来j个节点的结构是一个有效结构for (int i = n + 1; i >= 2; i--) {for (int j = 1; j <= m; j++) {dp[i][j] = Math.max(dp[i + size[i]][j], val[i] + dp[i + 1][j - 1]);}}// dp[2][m] : 2 ~ n范围上,选择m个节点一定要形成有效结构的情况下,最大的累加和// 最后来到dfn序为1的节点,一定是原始的0号节点// 原始0号节点下方一定挂着有效结构// 并且和补充的0号节点一定能整体连在一起,没有任何跳跃连接// 于是整个问题解决return nums[0]+dp[2][m];}// u这棵子树的节点数返回public static int f(int u) {int i = ++dfnCnt;val[i] = nums[u];size[i] = 1;for (int ei = head[u], v; ei > 0; ei = next[ei]) {v = to[ei];size[i] += f(v);}return size[i];}}
相关文章:
树 形 DP (dnf序)
二叉搜索子树的最大键值 /*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode() : val(0), left(nullptr), right(nullptr) {}* TreeNode(int x) : val(x), left(nullptr), right(null…...
React的生命周期?
React的生命周期分为三个主要阶段:挂载(Mounting)、更新(Updating)和卸载(Unmounting)。 1、挂载(Mounting) 当组件实例被创建并插入 DOM 时调用的生命周期方法&#x…...
c# - - - ASP.NET Core 网页样式丢失,样式不对
c# - - - ASP.NET Core 网页样式丢失,样式不对 问题 正常样式是这样的。 修改项目名后,样式就变成这样了。底部的内容跑到中间了。 解决 重新生成解决方案,然后发布网站。 原因: 修改项目名之前的 div 上有个这个自定义属…...
Cannot find module ‘html-webpack-plugin
当你在使用Webpack构建项目时遇到Cannot find module html-webpack-plugin这样的错误,这意味着Webpack在构建过程中找不到html-webpack-plugin模块。要解决这个问题,你需要确保已经正确安装了html-webpack-plugin模块,并且在Webpack配置文件中…...
vue、react部署项目的 hashRouter 和 historyRouter模式
Vue 项目 使用 hashRouter 如果你使用的是 hashRouter,通常不需要修改 base,因为 hashRouter 使用 URL 的哈希部分来管理路由,这部分不会被服务器处理。你只需要确保 publicPath 设置正确即可。 使用 historyRouter 如果你使用的是 histo…...
Qt 实现抽屉效果
1、实现效果和UI设计界面 2、工程目录 3、mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QToolButton> #include <QPushButton> #include <vector> using namespace std;QT_BEGIN_NAMESPACE namespace…...
windows上启动Kafka
官网下载 如:kafka_2.13-2.4.0.tgz 新版集成了Zookeeper ,无需另行下载 解压 至D:\Kafka\kafka_2.13-2.4.0 下 配置Kafka(可跳过) Zookeeper配置 kafka\config\zookeeper.properties下修改dataDir路径(Zookeeper数据目录)dataDirD:\\Program…...
贪心系列专题篇三
目录 单调递增的数字 坏了的计算器 合并区间 无重叠区间 用最少数量的箭 声明:接下来主要使用贪心法来解决问题!!! 单调递增的数字 题目 思路 如果我们遍历整个数组,然后对每个数k从[k,0]依次遍历寻找“单调递…...
Java中两个集合取差集
Java中两个集合取差集 说明: 集合A ListA: search archive relation test 集合B ListB: search search-gejunhao archive-gejunhao archive system 需求: 现在要取存在于A但是不存在B中的元素 test 该如何实现 思路: 在Java中,如果你想要从一个集合ÿ…...
flask mysql数据迁移
flask 数据迁移 在Flask中使用数据库迁移,通常我们会结合SQLAlchemy和Alembic来管理数据库的迁移。以下是一个基本的数据迁移流程: 安装Flask-Migrate: pip install Flask-Migrate 配置Flask应用和数据库: from flask import Fla…...
Kylin系列(一)入门
Kylin系列(一)入门 目录 简介Kylin的特点安装与配置 环境要求安装步骤 基本概念 Cube维度与度量 Kylin的基本操作 数据准备Cube设计Cube构建查询与分析 最佳实践常见问题总结 简介 Apache Kylin 是一个开源的分布式分析引擎,提供 SQL 查询接口及多维分析&#x…...
pmp学习交流组队~
首先,来看看什么是PMP PMP指的是项目管理专业人士资格认证。它是由美国项目管理协会(Project Management Institute(PMI)发起的,严格评估项目管理人员知识技能是否具有高品质的资格认证考试。 pmp备考攻略本人推荐的参考资料比较多࿰…...
公司常用的监控软件有哪些?2024年六大公司监控软件良心推荐!
在现代企业管理中,监控软件不仅可以帮助提高员工生产力,还可以确保企业数据的安全和保护。小编分享六款公司监控软件,能够满足不同企业的需求,提升管理效率和信息安全。 一、值得推荐的监控软件 1. 固信软件 固信软件https://ww…...
DNS解析异常--排查验证
目录 1.脚本 2.解析结果 3.脚本详解 1.脚本 for j in {1..100}; do for i in $domain1 $domain2; do echo $i; dig $i $dns服务器1 short; sleep 1; dig $i $dns服务器2 short ; sleep 1; done; sleep 2; done; 2.解析结果 ## 域名的解析实际IP: ## $domain1 $IP1 ## $do…...
OpenCV库学习之Canny边缘检测模块
OpenCV库学习之Canny边缘检测模块 一、简介 Canny边缘检测是OpenCV库中一个非常著名的边缘检测算法模块,由John F. Canny在1986年提出。该算法通过多个步骤来确定图像中的边缘,包括噪声降低、梯度计算、非极大值抑制、双阈值检测和边缘跟踪等。Canny边缘…...
Python 教程(七):match...case 模式匹配
目录 专栏列表前言基本语法match 语句case 语句 模式匹配的类型示例具体值匹配类型匹配序列匹配星号表达式命名变量复杂匹配 模式匹配的优势总结 专栏列表 Python教程(一):环境搭建及PyCharm安装Python 教程(二)&…...
Python小项目实战:杨辉三角
题目要求 编写python程序,实现输入正整数n,输出一个n层的杨辉三角,要求打印显示的时候左右对称 比如,输入7,返回结果如图所示 解决思路 generate_pascals_triangle(n) 函数: 生成一个包含 n 层的杨辉三角。 初始化第…...
java注解与反射(非常详细, 带有很多样例)
下面是详细地讲解 Java 中的注解与反射,并提供了很多的示例来帮助理解。 Java 注解(Annotations) 1. 注解的基本概念 注解(Annotation)是 Java 5 引入的一种用于为代码元素(类、方法、字段、参数等&…...
模拟实现短信登录功能 (session 和 Redis 两种代码实例) 带前端演示
目录 整体流程 发送验证码 短信验证码登录、注册 校验登录状态 基于 session 实现登录 实现发送短信验证码功能 1. 前端发送请求 2. 后端处理请求 3. 演示 实现登录功能 1. 前端发送请求 2. 后端处理请求 校验登录状态 1. 登录拦截器 2. 注册拦截器 3. 登录完整…...
C# Parallel设置最大并发度
背景 以前用Parallel都是直接用,今天在处理pdf时发现不是很快,特别是有时居然卡死了,异常是有处理的,但没有爆出来,不知道问题在哪。 老老实实不用多线程,一个多小时觉得还是太累。 用的话,部…...
Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密
在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...
通过 Ansible 在 Windows 2022 上安装 IIS Web 服务器
拓扑结构 这是一个用于通过 Ansible 部署 IIS Web 服务器的实验室拓扑。 前提条件: 在被管理的节点上安装WinRm 准备一张自签名的证书 开放防火墙入站tcp 5985 5986端口 准备自签名证书 PS C:\Users\azureuser> $cert New-SelfSignedCertificate -DnsName &…...
Python 高效图像帧提取与视频编码:实战指南
Python 高效图像帧提取与视频编码:实战指南 在音视频处理领域,图像帧提取与视频编码是基础但极具挑战性的任务。Python 结合强大的第三方库(如 OpenCV、FFmpeg、PyAV),可以高效处理视频流,实现快速帧提取、压缩编码等关键功能。本文将深入介绍如何优化这些流程,提高处理…...
Python竞赛环境搭建全攻略
Python环境搭建竞赛技术文章大纲 竞赛背景与意义 竞赛的目的与价值Python在竞赛中的应用场景环境搭建对竞赛效率的影响 竞赛环境需求分析 常见竞赛类型(算法、数据分析、机器学习等)不同竞赛对Python版本及库的要求硬件与操作系统的兼容性问题 Pyth…...
GraphQL 实战篇:Apollo Client 配置与缓存
GraphQL 实战篇:Apollo Client 配置与缓存 上一篇:GraphQL 入门篇:基础查询语法 依旧和上一篇的笔记一样,主实操,没啥过多的细节讲解,代码具体在: https://github.com/GoldenaArcher/graphql…...
阿里云Ubuntu 22.04 64位搭建Flask流程(亲测)
cd /home 进入home盘 安装虚拟环境: 1、安装virtualenv pip install virtualenv 2.创建新的虚拟环境: virtualenv myenv 3、激活虚拟环境(激活环境可以在当前环境下安装包) source myenv/bin/activate 此时,终端…...
CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?
在现代前端开发中,Utility-First (功能优先) CSS 框架已经成为主流。其中,Tailwind CSS 无疑是市场的领导者和标杆。然而,一个名为 UnoCSS 的新星正以其惊人的性能和极致的灵活性迅速崛起。 这篇文章将深入探讨这两款工具的核心理念、技术差…...
OPENCV图形计算面积、弧长API讲解(1)
一.OPENCV图形面积、弧长计算的API介绍 之前我们已经把图形轮廓的检测、画框等功能讲解了一遍。那今天我们主要结合轮廓检测的API去计算图形的面积,这些面积可以是矩形、圆形等等。图形面积计算和弧长计算常用于车辆识别、桥梁识别等重要功能,常用的API…...
