算法练习记录

dp(完全,线性,树状,状压,数位)>= 搜索 == 基础算法(二分,前缀和,高精度,公约数,公倍数,质数,排序) > 数据结构(树的构造,树的遍历,公共祖先,链表,树状数组,队列) > 图论(并查集,diji,floyd,prim,拓扑) ≈ 数论

C++ 头文件

数据流输入/输出:cin>>,cout<<的头文件:#include

c语言输入流:#include <stdio.h>

算法类函数:sort()…的头文件 #include

各个数学函数:max(),min(),sqrt()…的头文件 #include <math.h> 或 #include

字符串操作的头文件 #include 或 #include

结构类的头文件:

链表 #include

图 #include

队列 #include

迭代器 #include

栈 #include

闰年:两个条件均可(能被4整除不能被100整除)(能被400整除)

动态规划

题单:

目录
背包问题
背包问题初始化总结
AcWing 2. 01背包问题
AcWing 3. 完全背包问题
AcWing 4. 多重背包问题
AcWing 5. 多重背包问题 II
AcWing 9. 分组背包问题

线性DP
AcWing 898. 数字三角形
AcWing 895. 最长上升子序列
AcWing 896. 最长上升子序列 II(贪心)
AcWing 897. 最长公共子序列
AcWing 902. 最短编辑距离
AcWing 899. 编辑距离

区间DP
AcWing 282. 石子合并(m i n minmin)

计数类DP
AcWing 900. 整数划分(完全背包求方案数,体积恰好)

数位统计DP
AcWing 338. 计数问题

状态压缩DP
AcWing 291. 蒙德里安的梦想
AcWing 91. 最短Hamilton路径

树形DP
AcWing 285. 没有上司的舞会

记忆化搜索
AcWing 901. 滑雪

一.从记忆化搜索到递推

启发思路:选或不选—》状态转移方程

dp三步走:

  1. 思考回溯写法
  2. 改成记忆化搜索
  3. 1:1翻译成递推

举例:打家劫舍

1.思考回溯写法

dfs(i,nums):意味着找前i个数的最大和

对于第i个数选还是不选,

class Solution {
public:int rob(vector<int>& nums) {int n = nums.size();return dfs(n-1,nums);}int dfs(int i,vector<int> nums){if(i<0) return 0;return max(dfs(i-1,nums),dfs(i-2,nums)+nums[i]);}
};

2.改成记忆化搜索

就例如2已经多次进行了完整的dfs,可以进行了一次的时候就将其记录在缓存数组中,有用则调用

class Solution {
public:vector<int> memo;int rob(vector<int>& nums) {int n = nums.size();memo.resize(n,-1);return dfs(n-1,nums);}int dfs(int i,vector<int> nums){if(i<0) return 0;if(memo[i]!=-1) return memo[i];int res = max(dfs(i-1,nums),dfs(i-2,nums)+nums[i]);memo[i] = res;return res;}
};

3.1:1翻译成递推

既然我们知道从哪个点可以“归到哪个点”,那我们就舍弃“递”的过程,就直接“归”,3=2+1,4=3+2,也可以是是自下而上去递,这就叫“递推”

f为dfs的结果数组

自下而上,当前点不选就意味着选下面的点

class Solution {
public:int rob(vector<int>& nums) {int n = nums.size();vector<int> merge(n,-1);if(n==1) return nums[0];else if(n==2) return max(nums[0],nums[1]);merge[0]=nums[0];merge[1]=max(nums[0],nums[1]);for(int i=2;i<=n-1;i++)merge[i] = max(merge[i-1],merge[i-2]+nums[i]);return merge[n-1];}
};

因为只涉及了三个变量可以再进一步优化为空间复杂度为O(1)

class Solution {
public:int rob(vector<int>& nums) {int n = nums.size();int a,b,c;if(n==1) return nums[0];else if(n==2) return max(nums[0],nums[1]);a=nums[0];b=max(nums[0],nums[1]);for(int i=2;i<=n-1;i++){c = max(b,a+nums[i]);a=b;b=c;}return c;}
};

二.0-1背包

1.每种只能选一个

    int findTargetSumWays(vector<int>& weight, vector<int>& value,int c) {return dfs(weight,value,c,weight.size()-1);}int dfs(vector<int>& weight, vector<int>& value,int c,int i){if(i<0) return 0;if(c<weight[i]) return dfs(weight,value,c,i-1);return max(dfs(weight,value,c,i-1),dfs(weight,value,c-weight[i],i-1)+value[i]);}

2.leetcode 102题

1.分析状态转移方程

2.写出dfs

3.写出递推

1.创建同dfs结果值的f数组,并为其以边界条件附初始值,边界2.循环(对每个点选或不选)为f数组赋值,循环3.优化空间复杂度(一般来说,空间都能优化到影响的变量数-1维),优化
class Solution {// 从个体,选or不选,状态转移,转为递推public int findTargetSumWays(int[] nums, int target) {int sum = 0;for(int i:nums) sum+=i;sum+=target;//假设添加正号的数的和是p,添加负号的数就是数组和s-p,所以target = p-(s-p) = 2p-s,则p = (target+s)/2// 1.target+p一定为偶数,2.且大于等于0if(sum<0||sum%2==1) return 0;return dfs(nums,sum/2,nums.length-1);}public int dfs(int[] nums,int t,int n){if(n<0) return t==0?1:0;if(t<nums[n]) return dfs(nums,t,n-1);else return dfs(nums,t,n-1)+dfs(nums,t-nums[n],n-1);}
}

1.递推,两行解决

class Solution {// 从个体,选or不选,状态转移,转为递推public int findTargetSumWays(int[] nums, int target) {int sum = 0,n = nums.length;for(int i:nums) sum+=i;sum+=target;//假设添加正号的数的和是p,添加负号的数就是数组和s-p,所以target = p-(s-p) = 2p-s,则p = (target+s)/2// 1.target+p一定为偶数,2.且大于等于0if(sum<0||sum%2==1) return 0;sum /= 2;int[][] f = new int[2][sum+1];f[0][0] = 1;// n:i==0时即N<0时// n\sum 0 1 2 3 4...// n<0  // 1for(int i=0;i<n;i++){// sumfor(int j=0;j<=sum;j++){if(j<nums[i]) f[(i+1)%2][j] = f[i%2][j];else f[(i+1)%2][j] = f[i%2][j]+f[i%2][j-nums[i]];}}return f[n%2][sum];}   
}

2.递推优化空间为一行

class Solution {// 从个体,选or不选,状态转移,转为递推public int findTargetSumWays(int[] nums, int target) {int sum = 0,n = nums.length;for(int i:nums) sum+=i;sum+=target;//假设添加正号的数的和是p,添加负号的数就是数组和s-p,所以target = p-(s-p) = 2p-s,则p = (target+s)/2// 1.target+p一定为偶数,2.且大于等于0if(sum<0||sum%2==1) return 0;sum /= 2;int[] f = new int[sum+1];// 下一层只依赖上层,不依赖本层f[0] = 1;for(int i=0;i<n;i++){// 这里再j<nums[i]停止循环的原因,就是当满足此条件直接等于上层值for(int j=sum;j>=nums[i];j--){f[j] = f[j-nums[i]]+f[j];}}return f[sum];}}

3.leetcode 494题

这里也是选择在哪加正号,是选或不选的问题-》01背包

设选正数的和为p,总和为s,则负数和为s-p,那么t=p-(s-p)=2p-s,则右面为常量式子p=(t+s)/2,那么就转换为,在数组中选出一些正数其和恰好与p即(t+s)/2相等

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int sum=0;for(auto i:nums) sum+=i;sum+=target;//sum就是tif(sum<0||sum%2==1) return 0;return dfs(nums,sum/2,nums.size()-1);}int dfs(vector<int>& nums, int target,int i){if(i<0) return target==0?1:0;if(target<0) return 0;return dfs(nums,target,i-1)+dfs(nums,target-nums[i],i-1);}
};

每个结点向下是选或不选,确定下一个结点,再调用dfs返回选或不选的dfs结果之和

转换为递推 1.两个影响dfs结果的变量,target,i 3.初始值是i<0时 c=0时此时加一,因为i<0取不到,所以i再往上扩展一层使其为i=0,其实是i=-1

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int n = nums.size();int sum=0;for(auto i:nums) sum+=i;sum+=target;//sum就是tif(sum<0||sum%2==1) return 0;sum/=2;vector<vector<int>> ves(n+1, vector<int>(sum+1,0));ves[0][0] = 1;for(int i=0;i<n;i++){for(int j=0;j<=sum;j++){if(j<nums[i]) ves[i+1][j]=ves[i][j];else ves[i+1][j] = ves[i][j]+ves[i][j-nums[i]];}}return ves[n][sum];}
};

空间优化,只用两个数组

要计算i+1这个数组的值那么i-1这个数组就用不到了,可以直接将i-1替换为i+1数组

就是对两个数组进行切换%2就可以

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int n = nums.size();int sum=0;for(auto i:nums) sum+=i;sum+=target;//sum就是tif(sum<0||sum%2==1) return 0;sum/=2;vector<vector<int>> ves(2, vector<int>(sum+1,0));ves[0][0] = 1;for(int i=0;i<n;i++){for(int j=0;j<=sum;j++){if(j<nums[i]) ves[(i+1)%2][j]=ves[i%2][j];else ves[(i+1)%2][j] = ves[i%2][j]+ves[i%2][j-nums[i]];}}return ves[n%2][sum];}
};

那能不能只用一个数组呢?

先从左向右算,如下图会把前面的给覆盖掉

那么从右向左算呢?

可以且不会被覆盖

class Solution {
public:int findTargetSumWays(vector<int>& nums, int target) {int n = nums.size();int sum=0;for(auto i:nums) sum+=i;sum+=target;//sum就是tif(sum<0||sum%2==1) return 0;sum/=2;vector<int> ves(sum+1,0);ves[0] = 1;//反过来不越界的技巧for(int i=0;i<n;i++){for(int j=sum;j>=nums[i];j--){ves[j] = ves[j]+ves[j-nums[i]];}}return ves[sum];}
};

三.完全背包

1.LeetCode322题

选n种物品,选了还能选

写出dfs超时

class Solution {
public:int coinChange(vector<int>& coins, int amount) {int n = coins.size();int ans = dfs(coins,amount,n-1);return ans==1000000?-1:ans;}int dfs(vector<int>& coins, int amount,int i){if(i<0){if(amount==0) return 0;else return 1000000;}if(amount<coins[i]) return dfs(coins,amount,i-1);return min(dfs(coins,amount,i-1),dfs(coins,amount-coins[i],i)+1);}
};

改成高维数组

class Solution {
public:int coinChange(vector<int>& coins, int amount) {int n = coins.size();vector<vector<int>> ves(n+1,vector<int>(amount+1,1000000));//实际上是i==-1ves[0][0] = 0;for(int i=1;i<=n;i++){for(int j=0;j<=amount;j++){if(j<coins[i-1]) ves[i][j] = ves[i-1][j];else ves[i][j] = min(ves[i-1][j],ves[i][j-coins[i-1]]+1);}}return ves[n][amount]==1000000?-1:ves[n][amount];}};

减少数组空间复杂度

class Solution {
public:int coinChange(vector<int>& coins, int amount) {int n = coins.size();vector<vector<int>> ves(2,vector<int>(amount+1,1000000));//实际上是i==-1ves[0][0] = 0;for(int i=1;i<=n;i++){for(int j=0;j<=amount;j++){if(j<coins[i-1]) ves[i%2][j] = ves[(i-1)%2][j];else ves[i%2][j] = min(ves[(i-1)%2][j],ves[i%2][j-coins[i-1]]+1);}}return ves[n%2][amount]==1000000?-1:ves[n%2][amount];}};

为数组降维

class Solution {
public:int coinChange(vector<int>& coins, int amount) {int n = coins.size();vector<int> ves(amount+1,1000000);//实际上是i==-1ves[0] = 0;for(int i=1;i<=n;i++){for(int j=coins[i-1];j<=amount;j++){ves[j] = min(ves[j],ves[j-coins[i-1]]+1);}}return ves[amount]==1000000?-1:ves[amount];}};

最终优化什么是时候向前向后?

状态转移方程依赖,i的前,i的中,倒序:因为这样才能不影响i慢慢向前

状态转移方程依赖,i的前,i+1的前,正序:因为这样才能去依赖i+1慢慢向前

四.线性背包

1.LeetCode1143题:最长公共子串

写出dfs

class Solution {
public:int longestCommonSubsequence(string text1, string text2) {int n = text1.size(),m = text2.size();return dfs(text1,text2,n-1,m-1);}int dfs(string text1, string text2,int i,int j){if(i<0||j<0) return 0;if(text1[i]==text2[j]) return dfs(text1,text2,i-1,j-1)+1;else return max(dfs(text1,text2,i,j-1),dfs(text1,text2,i-1,j));}
};

转为二维递推

class Solution {
public:int longestCommonSubsequence(string text1, string text2) {int n = text1.size(),m = text2.size();vector<vector<int>> f(n+1,vector<int>(m+1,0));for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){f[i][j] = text1[i-1]==text2[j-1]?f[i-1][j-1]+1:max(f[i][j-1],f[i-1][j]);}}return f[n][m];}
}

转为一维递推(加个临时变量)

class Solution {
public:int longestCommonSubsequence(string text1, string text2) {int n = text1.size(),m = text2.size();vector<int> f(m+1,0);for(int i=1;i<=n;i++){int pre = f[0];for(int j=1;j<=m;j++){int tmp = f[j];f[j] = text1[i-1]==text2[j-1]?pre+1:max(f[j-1],f[j]);pre = tmp;}}return f[m];}
}

2.LeetCode72题:编辑距离

dfs

class Solution {
public:int minDistance(string word1, string word2) {int n = word1.size(),m = word2.size();return dfs(word1,word2,n-1,m-1);}int dfs(string word1, string word2,int i,int j){if(i<0) return j+1;if(j<0) return i+1;if(word1[i]==word2[j]) return dfs(word1,word2,i-1,j-1);else{int a=dfs(word1,word2,i-1,j),b=dfs(word1,word2,i,j-1),c=dfs(word1,word2,i-1,j-1);if(a<=b&&a<=c) return a+1;else if(b<=c) return b+1;else return c+1;}}
};

转为递推

class Solution {
public:int minDistance(string word1, string word2) {int n = word1.size(),m = word2.size();vector<vector<int>> f(n+1,vector<int>(m+1,0));for(int i=0;i<n+1;i++) f[i][0]=i;for(int j=0;j<m+1;j++) f[0][j]=j;for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){if(word1[i-1]==word2[j-1]) f[i][j] = f[i-1][j-1];else{int a=f[i-1][j],b=f[i][j-1],c=f[i-1][j-1];f[i][j]=min(min(a,b),c)+1; }}}return f[n][m];}
}

转为一维

class Solution {
public:int minDistance(string word1, string word2) {int n = word1.size(),m = word2.size();vector<int> f(m+1,0);for(int j=0;j<m+1;j++) f[j]=j;for(int i=1;i<=n;i++){int pre = f[0];f[0]=i;//每一行初始值都为ifor(int j=1;j<=m;j++){int tmp = f[j];if(word1[i-1]==word2[j-1]) f[j] = pre;else{int a=f[j],b=f[j-1],c=pre;f[j]=min(min(a,b),c)+1; }pre = tmp;}}return f[m];}
}

3.LeetCode300题: 最长递增子序列

dfs实现

class Solution {
public:int lengthOfLIS(vector<int>& nums) {int n = nums.size();int ans = 0;for(int i=0;i<n;i++) ans = max(ans,dfs(nums,i));return ans;}int dfs(vector<int>& nums,int n){if(n==0) return 1;int ans = 0;for(int i=0;i<n;i++) if(nums[n]>nums[i]) ans = max(ans,dfs(nums,i));return ans+1;}
};

转为递推

class Solution {
public:int lengthOfLIS(vector<int>& nums) {int n = nums.size();int ans = 0;vector<int> f(n,0);f[0]=1;for(int i=0;i<n;i++){int res = 0;for(int j=0;j<i;j++){if(nums[i]>nums[j]) res = max(res,f[j]);}f[i] = res+1;}for(int i=0;i<n;i++) ans = max(ans,f[i]);return ans;}
}

思路三:把数组排序去重后把它与原数组计算一个最长公共子序列得到的就是最长递增子序列,如果最长递增子序列允许重复就不用去重了

Dilworth 定理

把序列分成不递增子序列的最少个数==序列的最长递增子序列长度

五.树形dp

1.LeetCode543题:二叉树的直径

class Solution {
public:int ans = 0;int diameterOfBinaryTree(TreeNode* root) {dfs(root);return ans;}//计算左右子树的最大深度int dfs(TreeNode* root){if(root==nullptr) return -1;int left = dfs(root->left);int right = dfs(root->right);ans = max(ans,left+right+2);return max(left,right)+1;}
};

2.Leetcode124题:二叉树的最大路径和(直径变题)

class Solution {
public:int ans = -9999;int maxPathSum(TreeNode* root) {dfs(root);return ans;}int dfs(TreeNode* root){if(root==nullptr) return 0;int left_val = dfs(root->left);int right_val = dfs(root->right);ans = max(ans,left_val+right_val+root->val);return max(max(left_val,right_val)+root->val,0);}
};

3.LeetCode2246:相邻字符不同的最长路径(类内函数的使用防止内存溢出)

class Solution {
public:int longestPath(vector<int> &parent, string &s) {int n = parent.size();vector<vector<int>> g(n);for (int i = 1; i < n; ++i)g[parent[i]].push_back(i);int ans = 0;//function<int(int)> 是 C++ 中的一个函数类型,表示一个以 int 为参数类型,返回值为 int 类型的函数。后面加[capture clause] (parameters) -> return_type {函数体}//类内函数function<int(int)> dfs = [&](int x) -> int {int maxLen = 0;for (int y : g[x]) {int len = dfs(y) + 1;if (s[y] != s[x]) {ans = max(ans, maxLen + len);maxLen = max(maxLen, len);}}return maxLen;};dfs(0);return ans + 1;}
};

4.Leetcode337题:打家劫舍三(对树的选或不选)

class Solution {
public:unordered_map <TreeNode*, int> f, g;void dfs(TreeNode* node) {if (!node) {return;}dfs(node->left);dfs(node->right);f[node] = node->val + g[node->left] + g[node->right];g[node] = max(f[node->left], g[node->left]) + max(f[node->right], g[node->right]);}int rob(TreeNode* root) {dfs(root);return max(f[root], g[root]);}
};

六.状态机dp

其他

1.LeetCode5题最长回文子串

class Solution {public String longestPalindrome(String s) {int n = s.length();int length = 1; // 最长回文子串的长度int start = 0; // 最长回文子串的起始位置boolean[][] dp = new boolean[n][n]; // dp[j][i]表示子串s[j:i]是否为回文串for(int i = 0; i < n; i++){// 以i为终点,往回枚举起到jfor(int j=i;j>=0;j--){if(i==j) dp[j][i] = true;else if(i==j+1) dp[j][i] = (s.charAt(i)==s.charAt(j));else dp[j][i] = (s.charAt(i)==s.charAt(j))&& dp[j+1][i-1];if(dp[j][i] && (i-j+1)>length){length = i-j+1;start = j;}}    }return s.substring(start,start+length);}
}

二分查找

在g找x的左边界(返回迭代器)查找大于或等于指定值的第一个元素的位置

auto it = lower_bound(g.begin(), g.end(), x);

在g找x的右边界(返回迭代器)查找大于指定值的第一个元素

auto it = upper_bound(g.begin(), g.end(), x);

注意:上述两个方法只有在一定能找到该值才会有效果

取下标

int m=distance(nums.begin(), sr)

*it取值

也可取值并赋值到原数组中

*it = x;

class Solution {
public:int shipWithinDays(vector<int>& weights, int days) {//获取货物的最大值int ma = *max_element(weights.begin(),weights.end());int left = ma;int right = 1e9;while(left<right){int mid = left + (right-left)/2;if(gerDay(mid,weights)>days) left = mid+1;else right = mid; }return right;}//返回该运载量所需要的天数;int gerDay(int m,vector<int>& weights){int sumday = 0;for(int i=0;i< weights.size();){int weight = m;while(i<weights.size()&&weight>=weights[i]){weight-=weights[i];i++;}sumday+=1;}return sumday;}
};

class Solution {
public:int hour;int f(vector<int>& piles,int x){long hours = 0;for (int i = 0; i < piles.size(); i++) {hours += piles[i] / x;if (piles[i] % x > 0) {hours++;}}return hours;}int minEatingSpeed(vector<int>& piles, int h) {hour = h;long long l=1,r = 1000000000 + 1;while(l<r){long long mid = l+(r-l)/2;if(f(piles,mid)>hour) l = mid+1;else r = mid;}return l;}
};

图论

1.prim

#include <bits/stdc++.h>
using namespace std;
int n,m,ans = 0;//一.定义
//1.1
int mapdist[1000][1000];
//1.2
vector<int> v[1000];
//1.3
int mindist[1000];//此时每个点到最短路的长度//二.prim过程 
void prim(){//2.1定义防回代码 vector<bool> visted(1000,false);int last = 1;mindist[last] = 0;for(int i=1;i<=n;i++){visted[last] = true;//2.2.1核心代码 扩散该节点 for(int j=1;j<=n;j++) mindist[j] = min(mindist[j],mapdist[last][j]);int k=-1;//2.2.2找到下一个最短举例节点 for(int j=1;j<=n;j++) if(!visted[j]&&(k<0||mindist[j]<mindist[k])) k=j;last = k;//不同代码,最短路的最终路径 ans+=mindist[k];}
}int main()
{cin>>n>>m;//1.4 初始化举例 memset(mapdist,0x3f,sizeof(mapdist));memset(mindist,0x3f,sizeof(mindist));for(int i=0;i<m;i++){int v1,v2,d;cin>>v1>>v2>>d;v[v1].push_back(v2);v[v2].push_back(v1);mapdist[v1][v2] = mapdist[v2][v1] = d;}prim();cout<<ans;return 0;
}

2.dijisktra

#include<bits/stdc++.h>
using namespace std;int n,m,c1,c2;
int zyrenshu=0;
int pathsize=0;
int renshu[500];//1.定义
//1.1距离
int mapdist[500][500];
//1.2结点 
vector<int> v[500];
//1.3最短路
int mindist[500];//2.构造
void dijikstra(){//2.1检验防回数组vector<int> visited(n,false);int last = c1;mindist[last] = 0;for(int i=0;i<n;i++){visited[last] = true;//2.2.1扩散for(int j=0;j<n;j++) mindist[j] = min(mindist[j],mindist[last]+mapdist[j][last]);//2.2.2寻找int k=-1;for(int j=0;j<n;j++) if(!visited[j]&&(k<0||mindist[j]<mindist[k])) k=j;last = k;}
}//3.dfs
void dfs(int cur,int changdu,int curzyrenshu){if(mindist[cur]<changdu) return;if(cur==c2){pathsize++;zyrenshu = max(zyrenshu,curzyrenshu);}else for(auto m:v[cur]) dfs(m,changdu+mapdist[m][cur],renshu[m]+curzyrenshu);
}int main(){cin>>n>>m>>c1>>c2;//1.4memset(mapdist,0x3f,sizeof(mapdist));memset(mindist,0x3f,sizeof(mindist));for(int i=0;i<n;i++) cin>>renshu[i];for(int i=0;i<m;i++){int v1,v2,d;cin>>v1>>v2>>d;v[v1].push_back(v2);v[v2].push_back(v1);mapdist[v1][v2] = mapdist[v2][v1] = d;}dijikstra();dfs(c1,0,renshu[c1]);cout<<pathsize<<" "<<zyrenshu;
}

3.并查集

//将开启爱好圈子的第一个人作为标杆,相同爱好的人有相同的标杆,相同人的不同爱好有相同的标杆
#include<bits/stdc++.h>
using namespace std;
int father[1001]={0},cluster[1001]={0};
vector<int> isroot(1001,0);
int n;int findfather(int x){if(x!=father[x]) father[x] = findfather(father[x]);return father[x];
}
void _union(int x,int y){if(findfather(x)!=findfather(y)) father[findfather(x)] = findfather(y);
}int main(){cin>>n;for(int i=1;i<=n;i++) father[i] = i;for(int i=1;i<=n;i++){int k;cin>>k;getchar();for(int j=0;j<k;j++){int h;cin>>h;if(cluster[h]==0) cluster[h] = i;_union(i,findfather(cluster[h]));}}for(int i=1;i<=n;i++) isroot[findfather(i)]++;sort(isroot.begin(),isroot.end(),greater<int>());int sum=0;for(int i=0;i<n;i++){if(isroot[i]!=0) sum++;else break;}cout<<sum<<endl;for(int i=0;i<sum;i++){if(!i) cout<<isroot[i];else cout<<" "<<isroot[i];}}

完全二叉树

判断用bfs

bool t = true;
void level(TreeNode* root){if(root==nullptr) return;queue<TreeNode*> q;q.push(root);bool t1=true;while(!q.empty()){TreeNode* cur = q.front();q.pop();le.push_back(cur->data);if(cur->left==nullptr){if(t1) t1 = false;}else{if(!t1) t = false;q.push(cur->left);}if(cur->right==nullptr){if(t1) t1 = false;}else{if(!t1) t = false;q.push(cur->right);}}
}
if(!t) "那么就不是完全二叉树" else "就是完全二叉树"

二叉搜索树

左小右大

遍历:BST 的中序遍历其实就是升序排序的结果

void BST(TreeNode* root, int target) {if(root==nullptr) return;if (root->val == target)// 找到目标,做点什么if (root->val < target) BST(root->right, target);if (root->val > target)BST(root->left, target);
}

构造:

TreeNode* BSTbuild(int start,int end){if(start>end) return nullptr;TreeNode* root = new TreeNode(treenums[start]);int mid=-1;for(int i=start+1;i<=end;i++){if(treenums[start]<=treenums[i]){mid = i;break;}}if(mid==-1) root->left = BSTbuild(start+1,end);else{root->left = BSTbuild(start+1,mid-1);root->right = BSTbuild(mid,end);}return root;
}

树的遍历

层序

void levelTravese(){queue<int> q;q.push(root);int num = 0;while (!q.empty()){int top = q.front();q.pop();printf("%d",top);if(num<N-1) printf(" ");++num;if(tree[top].right!=-1){q.push(tree[top].right);}if(tree[top].left!=-1){q.push(tree[top].left);}}
}

树的构造

前中-》

TreeNode* gouzao(vector<int> &preorder,int prestart,int preend,vector<int> &inorder,int instart,int inend){if(prestart>preend) return nullptr;TreeNode* root= new TreeNode(preorder[prestart]);int index = -1;for(int i=instart;i<=inend;i++){if(inorder[i]==preorder[prestart]){index = i;break;}}int cha = index-instart;//注意去开头之后的长度为插值root->left = gouzao(preorder,prestart+1,prestart+cha,inorder,instart,index-1);root->right = gouzao(preorder,prestart+cha+1,preend,inorder,index+1,inend);return root;
}
#include<bits/stdc++.h>
using namespace std;
struct TreeNode{int val; TreeNode *left=nullptr,*right=nullptr;TreeNode(int val){this->val = val;}
};
int n;
vector<int> preorder,inorder,postorder;
stack<int> st;TreeNode* build(vector<int> &preorder,int prestart,int preend,vector<int> &inorder,int instart,int inend){if(prestart>preend) return nullptr;TreeNode* root= new TreeNode(preorder[prestart]);int index = -1;for(int i=instart;i<=inend;i++){if(inorder[i]==preorder[prestart]){index = i;break;}}int cha = index-instart;root->left = gouzao(preorder,prestart+1,prestart+cha,inorder,instart,index-1);root->right = gouzao(preorder,prestart+cha+1,preend,inorder,index+1,inend);return root;
}
void posttraverse(TreeNode* root){if(root==nullptr) return;posttraverse(root->left);posttraverse(root->right);postorder.push_back(root->val);
}int main(){//由前序中序构造二叉树-》后序遍历cin>>n;string m1;int m2;for(int i=1;i<=2*n;i++){cin>>m1;if(m1=="Push"){cin>>m2;preorder.push_back(m2);st.push(m2);}else{inorder.push_back(st.top());st.pop();}}TreeNode* root = build(preorder,0,n-1,inorder,0,n-1);posttraverse(root);for(int i=0;i<n;i++){if(!i) cout<<postorder[i];else cout<<" "<<postorder[i];}
}

中后 如果参数是数组int (&post)[40]

TreeNode* build(vector<int> &in,int instart,int inend,vector<int>post,int poststart,int postend){if(poststart>postend) return nullptr;TreeNode *root = new TreeNode(post[postend]);int index;for(int i=instart;i<=inend;i++){if(in[i]==post[postend]){index = i;break;}}int charzhil = index - instart;//注意去结尾之后的长度为插值root->l = gouzao(in,instart,index-1,post,poststart,poststart+charzhil-1);root->r = gouzao(in,index+1,inend,post,poststart+charzhil,postend-1);return root;
}

LCA

TreeNode* zhao_zi(TreeNode* root,int val1,int val2){if(root==nullptr) return nullptr;if(root->val==val1||root->val==val2) return root;TreeNode* left=lca(root->left,val1,val2);TreeNode* right=lca(root->right,val1,val2);if(left!=nullptr&&right!=nullptr) return root;return left==nullptr?right:left;
}
#include<bits/stdc++.h>
using namespace std;
int n,m;
int s[10001];
unordered_set<int> se;
struct TreeNode{int val;TreeNode* left = nullptr,*right = nullptr;TreeNode(int val){this->val = val;}
};TreeNode* build(int start,int end){if(start>end) return nullptr;TreeNode* root = new TreeNode(s[start]);int index=-1;for(int i=start+1;i<=end;i++){if(root->val<=s[i]){index = i;break;}}if(index!=-1){root->left = build(start+1,index-1);root->right = build(index,end);}else{root->left = build(start+1,end);}return root;
}TreeNode* lca(TreeNode* root,int val1,int val2){if(root==nullptr) return nullptr;if(root->val==val1||root->val==val2) return root;TreeNode* left=lca(root->left,val1,val2);TreeNode* right=lca(root->right,val1,val2);if(left!=nullptr&&right!=nullptr) return root;return left==nullptr?right:left;
}int main(){cin>>n>>m;for(int i=0;i<m;i++){cin>>s[i];se.insert(s[i]);}TreeNode* root = build(0,m-1);;int a1,a2;for(int i=0;i<n;i++){cin>>a1>>a2;if(se.find(a1)==se.end()&&se.find(a2)==se.end()) {cout<<"ERROR: "<<a1<<" and "<<a2<<" are not found."<<endl;continue;}if(se.find(a1)==se.end()){cout<<"ERROR: "<<a1<<" is not found."<<endl;continue;}if(se.find(a2)==se.end()){cout<<"ERROR: "<<a2<<" is not found."<<endl;continue;}TreeNode* root1 = lca(root,a1,a2);if(root1->val==a1){cout<<a1<<" is an ancestor of "<<a2<<"."<<endl;}else if(root1->val==a2){cout<<a2<<" is an ancestor of "<<a1<<"."<<endl;}else{cout<<"LCA of "<<a1<<" and "<<a2<<" is "<<root1->val<<"."<<endl;}}
}

排序

快排

1.quickSort:

排左排右dfs

2.partition:

(1)随机选取建立一个标签srand(time(0));int m = rand()%(R-L+1) + L;

(2)初始化p1=l,p2=r,i=l流程:与随机数哨兵相等i++,小于哨兵p1++,i++,大于哨兵 p2++;

(3)返回vector { p1-1, p2+1 };

#include<bits/stdc++.h>
using namespace std;
void  swap(int &a,int&b){if(a==b) return;a = a^b;b = a^b;a = a^b;
}vector<int> partition(vector<int>& nums, int L, int R){srand(time(0));int m = rand()%(R-L+1) + L;m = nums[m];int p1 = L, p2 = R, i = L;while (i <= p2) {if (nums[i] < m) {swap(nums[i], nums[p1]);p1++;i++;} else if (nums[i] > m) {swap(nums[i], nums[p2]);p2--;	} else {i++;}}return vector<int> { p1-1, p2+1 };
}
//前序遍历
void quickSort(vector<int>& nums, int L, int R) {if(L>=R) return;vector<int> m = partition(nums,L,R);quickSort(nums,L,m[0]);quickSort(nums,m[1],R);
}int main(){vector<int>nums = {9,9,1,8,2,3,1};quickSort(nums,0,nums.size()-1);for(auto i:nums) cout<<" "<<i;
} 

归并

1.sort找中间,排左排右,后序位置进行merge

2.merge:(1)定义一个临时数组为临时数组赋初值(原数组)

			   (2)左,中放个指针,p临时数组指针,num随推进修改
#include <bits/stdc++.h>
using namespace std;vector<int> temp;
void merge(vector<int>& nums,int left,int mid,int right){for(int i=left;i<=right;i++) temp[i] = nums[i];int i = left,j = mid+1,p=left;while(p<=right){if(i==mid+1) nums[p++] = temp[j++];else if(j==right+1)  nums[p++] = temp[i++];else if(temp[i]<=temp[j]) nums[p++] = temp[i++]; else if(temp[i]>temp[j]) nums[p++] = temp[j++];}
}//后续遍历
void sort(vector<int>& nums,int left,int right){if(right<=left) return;int mid = left+(right-left)/2;sort(nums,left,mid);sort(nums,mid+1,right);merge(nums,left,mid,right);
}int main(){vector<int>nums = {0,9,1,3,9,6,8,6,1};int n = nums.size();temp.resize(n);sort(nums,0,n-1);for(auto i:nums) cout<<" "<<i;
}

逆序对

#include <iostream>
#include <vector>
using namespace std;vector<int> temp;
int reversePairs = 0;void merge(vector<int>& nums, int left, int mid, int right) {for (int i = left; i <= right; i++) temp[i] = nums[i];int i = left, j = mid + 1, p = left;while (p <= right) {if (i == mid + 1) nums[p++] = temp[j++];else if (j == right + 1)  nums[p++] = temp[i++];else if (temp[i] <= temp[j]) nums[p++] = temp[i++];else {nums[p++] = temp[j++];reversePairs += mid - i + 1; // 统计逆序对数量}}
}void sort(vector<int>& nums, int left, int right) {if (right <= left) return;int mid = left + (right - left) / 2;sort(nums, left, mid);sort(nums, mid + 1, right);merge(nums, left, mid, right);
}int main() {vector<int> nums = {9, 7, 5, 4, 6};int n = nums.size();temp.resize(n);sort(nums, 0, n - 1);cout << "逆序对总数:" << reversePairs << endl;return 0;
}

堆排序

#include <bits/stdc++.h>
using namespace std;void buildMaxHeap(vector<int>& nums) {int n = nums.size();for (int i = (n - 1 - 1) / 2; i >= 0; i--) {//从n-1的父亲节点开始遍历,然后依次自右向左再向上heapfiy  其中n-1为第n个元素的下标为n-1maxHeapify(nums, i, n);}
}void maxHeapify(vector<int>& nums, int i, int n) {while (i * 2 + 1 < n) {//当至少有一个孩子// 代表当前 i 节点的左右儿子;// 超出数组大小则代表当前 i 节点为叶子节点,不需要移位int lSon = 2 * i + 1;int rSon = 2 * i + 2;int large = i;if (lSon < n && nums[lSon] > nums[large]) large = lSon;if (rSon < n && nums[rSon] > nums[large]) large = rSon;if (large != i) {swap(nums[i], nums[large]);// 迭代判断对应子节点及其儿子节点的大小关系i = large;} else {break;}}
}vector<int> sortArray(vector<int>& nums) {// heapSort 堆排序int n = nums.size();// 将数组整理成大根堆buildMaxHeap(nums);for (int i = n - 1; i >= 1; --i) {// 依次弹出最大元素,放到数组最后,当前排序对应数组大小 - 1swap(nums[0], nums[i]);--n;maxHeapify(nums, 0, n);}return nums;
}int main(){sortArray(num);
}

数字运算技巧

1.最大公约数与最小公倍数

/*
求两个正整数 a 和 b 的 最大公约数 d
则有 gcd(a,b) = gcd(b,a%b)
证明:设a%b = a - k*b 其中k = a/b(向下取整)若d是(a,b)的公约数 则知 d|a 且 d|b 则易知 d|a-k*b 故d也是(b,a%b) 的公约数若d是(b,a%b)的公约数 则知 d|b 且 d|a-k*b 则 d|a-k*b+k*b = d|a 故而d|b 故而 d也是(a,b)的公约数因此(a,b)的公约数集合和(b,a%b)的公约数集合相同 所以他们的最大公约数也相同 证毕#
*/
int gcd(int a, int b) return b ? gcd(b,a%b):a; 

最大公约数:gcb(a,b)

由欧几里得辗转相除法:最小公倍数= a*b/gcb(a,b);

b:gcb(b,a%b):a;

2.素数(质数)判断

除1和本身没有其他除数

bool isPrime(int r) {if (r <= 1) return false;for (int i = 2; i <= sqrt(r); i++) if (r % i == 0) return false;return true;
}

由数的对称性(3×2=2×3)得知如果r在【2,r的平方根】之间没有倍数关系那么就为素数

3.进制转换

(1)10进制转r进制

vector<int> nums;
while (n) {nums.push_back(n % r);n /= r;
}
reverse(nums.begin(),nums.end());

以10进制转二进制举例:

每余2得到该数在二进制中的最后小位数

每除二相当于在二进制中右一一下

所以循环过后的位数是上升的所以反转

(2)r进制转10进制

int res = 0;
for (int i = 0; i < nums.size(); i++) res = res* r + nums[i];

相当于先左移再相加最低位

4.Ascll码表

5.高精度数字计算

(1)高精度加法

1.将字符串a,b反向导入到新建A,B数组

2.创建临时变量,并使用t对两个加法操作,对10取余放到C数组,除等

3.将C数组反向导出到c中

#include<bits/stdc++.h>
using namespace std;string add(string a,string b){vector<int>A,B;for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0');vector<int> C;int t=0;for(int i=0;i<A.size()||i<B.size();i++){if (i < A.size()) t += A[i];if (i < B.size()) t += B[i];C.push_back(t % 10);t /= 10;}if(t!=0) C.push_back(t);string c = "";for (int i = C.size() - 1; i >= 0; i--) {c+=to_string(C[i]);}return c;
}int main(){string a= "9999999999999999999999999";string b = "4324324299999999999999999999999";cout<<add(a,b);
} 

(2)高精度减法

条件:a>b

1.将字符串a,b反向导入到新建A,B数组

2.创建临时变量,遍历A数组并使用t对A加法操作,对t+10取10余放到C数组,若t《0 t=-1,则t=0;

3.将C数组反向导出到c中

#include<bits/stdc++.h>
using namespace std;string diff(string a, string b) {vector<int> A, B, C;for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');int t = 0;for (int i = 0; i < A.size(); i++) {t += A[i];if (i < B.size()) t -= B[i];C.push_back((t + 10) % 10);if (t < 0) t = -1;else t = 0;}string c;//if(C.size()>1&&C.back()==0) C.pop_back(); for (int i = C.size() - 1; i >= 0; i--) c += to_string(C[i]);return c;
}int main(){string a= "9990";string b = "1000";cout<<diff(a,b);
} 

(3)高精度乘法

vector<int> mul(vector<int>& A, int b) {vector<int> C;int t = 0;for (int i = 0; i < A.size() || t; i++) {if (i < A.size()) t += A[i] * b;C.push_back(t % 10);t /= 10;}while (C.size() > 1 && C.back() == 0) C.pop_back();return C;
}

(4)高精度除法

vector<int> div(vector<int>& A, int b, int& r) {vector<int> C(A.size());for (int i = 0; i < A.size(); i++) {r = r * 10 + A[i];C[i] = r / b;r %= b;}reverse(C.begin(), C.end());while (C.size() > 1 && C.back() == 0) C.pop_back();return C;
}

6.比较器的应用过程

  • 返回true不交换
  • 返回false交换

7.时间相关

时间安排,都安排成秒,再进行排序,从时间按转化为h:m:s就是

8.字母数字判断以及大小写转化

Isdigit()判断字符是否为数字

isalpha()判断此字符是否为字母

islower()判断此字符是否为小写字母

isupper()判断此字符是否为大写字母

isalnum()判断此字符是否为字母或数字

isspace()判断此字符是否为空格或转换符

如果是则输出1,不是就输出0

tolower()将此字符转为小写字母

toupper()将此字符转为大写字母

9.数字字母转化

字符串转数字

stoi():意思是把字符串转化为int型变量

stod():意思是把字符串转化为double型变量

字符转数字

i=j-‘0’;

数字转字符串

to_string():这个很简单,也很实用,功能就是把一个数字,只能将数字转化为字符串

字符转字符串

String(1,c):将字符型变成string类型返回字符串类型

10.其他

(1)数组初始化

memset(color,0,sizeof(color)):

第一个参数是开头指针,第二个是赋的值,第三个是所占内存大小

(2)int自动去除前面0

(3)排名重叠问题

如果是排名类的题目呢,有两个第一名就不要出现第二名了

(4)map降序

map容器默认按键大小升序排列,那怎么降序排列呢

(5)两个不等长的字符串比较

(6)四舍五入输出

先×n个10

再round(num);

另外

(7)sort取前不取后

Sort(work,work+3);前取后不取[0,3)->[0,2]

(8)输出格式

链接csdn

(9)获取输入

获取输入的一行

int main(){string input;getline(cin,input);vector<int> numbers;istringstream iss(input);int number;while (iss >> number) {numbers.push_back(number);}
}

(10)闰年是指

闰年和平年的主要区别在于闰年比平年多一天。具体来说,闰年是指每四年中有一个多出的日子,即2月份有29天而不是28天。

①非世纪年能被4整除,且不能被100整除的是闰年。(如2024年是闰年,1901年不是闰年)
②世纪年能被400整除的是闰年。(如2000年是闰年,1900年不是闰年)

11.优先队列

priority_queue 类模板的三个参数:输入类型为 ListNode*,堆容器类型为 vector<ListNode*>,比较函数类型声明为function<bool(ListNode*, ListNode*)>

方法:

是否为空:Pq.empty()

放入元素:Pq.push()

取堆顶元素:Pq.top()

删掉堆顶元素:Pq.pop()

priority_queue<ListNode*,vector<ListNode*>,function<bool(ListNode*,ListNode*)>> pq([](LustNode* a,ListNode* b){return a->val > b->val;});
class Solution {
public:int findKthLargest(vector<int>& nums, int k) {priority_queue<int,vector<int>,function<bool(int,int)>> pq([](int a,int b){return a>b;//每一次比较都是一次向下调整所以是小顶堆});for (int e : nums) {pq.push(e);if (pq.size() > k)  pq.pop();//如果大小超过了k就删掉堆顶}return pq.top();}
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/12933.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

深入浅出 ChatGPT 底层原理:Transformer

Transformer 在人工智能和自然语言处理领域,Transformer架构的出现无疑是一个里程碑式的突破。它不仅推动了GPT(Generative Pre-trained Transformer)等大型语言模型的发展,还彻底改变了我们处理和理解自然语言的方式。 GPT与Transformer GPT 近几年&#xff0c;人工智能技…

【C语言】js写一个冒泡顺序

用js写一个冒泡排序 当然可以。在JavaScript中&#xff0c;你可以使用递归的方式来实现冒泡排序算法。这是一个简单的示例&#xff1a; function bubbleSort(arr) { let len arr.length; if(len < 1){ return arr; // 如果数组只有一个元素或为空&#xff0c;直接返回 } //…

Leetcode3345. 最小可整除数位乘积 I

Every day a Leetcode 题目来源&#xff1a;3345. 最小可整除数位乘积 I 解法1&#xff1a;枚举 至多循环 10 次&#xff0c;一定会遇到个位数为 0 的数字&#xff0c;数位乘积是 0&#xff0c;一定是 t 的倍数。 所以暴力枚举即可。 代码&#xff1a; /** lc appleetcod…

element的from表单校验问题 —— 校验内容正确、但触发错误提示

问题&#xff1a;二次封装了el-radio&#xff0c;在选择后触发了form的校验&#xff0c;并提示了错误。 分析&#xff1a;输出radio选择后的value值是正确&#xff0c;但还是触发了错误校验提示&#xff0c;可能纯在以下几个问题 1. v-model 绑定的form参数和rules不一致 2. e…

工业相机选取

1.相机分类&#xff1a; 1.1 在相机曝光方式中&#xff0c;全局曝光和卷帘曝光是两种主流技术。CCD相机通常采用全局曝光方式&#xff0c;而CMOS相机则可能采用卷帘曝光。 面阵相机与全局曝光关联与区别 关联&#xff1a;面阵相机可以使用全局曝光作为曝光方式&#xff0c;但…

使用Windows自带的IIS搭建FTP服务端

1、启用IIS功能 2、打开IIS 3、将默认的站点删除 4、创建FTP服务端 &#xff08;1&#xff09;选中站点&#xff0c;然后点击鼠标邮件&#xff0c;点击添加FTP站点 &#xff08;2&#xff09;指定站点名称和物理路径 物理路径&#xff1a;FTP服务端数据的路径&#xff0c;F…

研界的福尔摩斯——扩增子+qPCR

微生物在生物地球化学循环、动植物健康等多种领域发挥作用&#xff0c;因此&#xff0c;精确测量微生物绝对丰度对理解其与人类健康、植物生长等的关系至关重要。 常规扩增子测序分析只能解析样本中的物种组成和其相对丰度信息&#xff0c;并不能反映样本每种微生物的真实数量…

期权懂|期权到期了,可以不行权吗?

期权小懂每日分享期权知识&#xff0c;帮助期权新手及时有效地掌握即市趋势与新资讯&#xff01; 期权到期了&#xff0c;可以不行权吗&#xff1f; 期权到期后&#xff0c;投资者并非必须行权。如果行权无利可图或不符合预期收益&#xff0c;可以选择放弃行权&#xff0c;让期…

SL1571B 输入5V2A或单节锂电池,升压12V 10W 升压恒压芯片

一、概述 SL1571B是一款高功率密度的异步升压转换器&#xff0c;专为便携式系统提供高效且小尺寸的解决方案。它内置MOS管&#xff0c;具有120mΩ功率开关&#xff0c;支持宽输入电压范围&#xff0c;并具备多种保护功能。 二、主要特性 输入电压范围&#xff1a;SL1571B的输…

接口测试vs功能测试

接口测试和功能测试的区别&#xff1a; 本文主要分为两个部分&#xff1a; 第一部分&#xff1a;主要从问题出发&#xff0c;引入接口测试的相关内容并与前端测试进行简单对比&#xff0c;总结两者之前的区别与联系。但该部分只交代了怎么做和如何做&#xff1f;并没有解释为什…

ubuntu20.04_从零LOD-3DGS的复现

环境要求 创建环境 conda create -n lod-3dgs python3.71. 安装CUDA11.6和相应cuDNN。 1.1 CUDA CUDA安装参考CUDA1&#xff1b;CUDA11.6&#xff0c;安装过程相似。 1.2 cuDNN 参考&#xff0c;下载对应版本后复制到对应CUDA里面。 cp cuda/lib64/* /usr/local/cuda-11…

IIS安装,Sql Server安装

在Windows操作环境下&#xff0c; 首先检查是否安装IIS&#xff0c;在“管理工具”中查看目录中是否存在Internet Information Services&#xff08;IIS&#xff09;的文件&#xff0c;存在则IIS已经安装成功。未安装则使用以下步骤&#xff1a; 1、使用winR打开控制面板&…

【LeetCode】【算法】64. 最小路径和

LeetCode 64. 最小路径和 题目描述 给定一个包含非负整数的 m x n 网格 grid &#xff0c;请找出一条从左上角到右下角的路径&#xff0c;使得路径上的数字总和为最小。 说明&#xff1a;每次只能向下或者向右移动一步。 思路 思路&#xff1a;这种题太典了&#xff0c;典…

win11安装wsa 安卓

今天和大家分享一个如何在windows10/11/12操作系统上使用Windows Subsystem for Android安卓APK应用系统的教程&#xff1b;网络上有很多教程&#xff0c;但是来回折腾很久也是各种问题&#xff0c;经过研究&#xff0c;找到一套完整有效的方案&#xff1b; 第一步、进入系统设…

美食网的设计与实现

摘 要 随着科技的发展、生活水平的提升&#xff0c;人们更加注重饮食搭配和饮食健康。通过网络技术来加强美食与健康知识的普及是当前一种可行的措施。通过网页浏览美食网&#xff0c;不仅可以普及每道美食的做法&#xff0c;通过制作美食来缓解心情&#xff0c;还可以通过美…

2024-2025年EI会议时间表,把握未来学术研讨机遇

2024-2025年多场国际学术会议将在中国多地举办&#xff0c;涵盖网络、通信、AI等领域&#xff0c;均支持EI等检索。会议时间、地点及检索信息已提供&#xff0c;涉及北京、淮北、深圳等城市。 以下是部分精品学术会议基本信息&#xff0c;欢迎点击链接查看&#xff1a; 第二届…

QML —— 圆形波浪进度条控件(附上源码)

效果 说明 QML中使用画布元素(canvas element),使用画布元素可画出各种各样的图形,同时允许脚本绘制。画布元素提供了一个依赖于分辨率的位图画布,也可以使用JavaScript脚本来绘制图形,制作游戏或者其它的动态图像。QML中的画布元素是基于HTML5的画布元素来完成的。    …

echarts引入自定义字体不起作用问题记录

echarts引入自定义字体不起作用问题记录 1、问题描述 初始化界面字体不作用&#xff0c;当界面更新后字体样式正常显示 2、原因描述 这通常是由于字体文件加载延迟导致的。ECharts 在初始化时可能还没有加载完字体文件&#xff0c;因此无法正确应用字体样式 3、解决方案 …

UE5.4 PCG 生成藤蔓墙体

一、新建Actor&#xff0c;添加Spline组件&#xff0c;挂上PCG组件&#xff0c;设置“墙体”和“植被”为静态网格体变量 二、编写PCG_Wall 1.生成墙体 2.生成墙体植被

【网络】子网掩码

> 作者&#xff1a;დ旧言~ > 座右铭&#xff1a;松树千年终是朽&#xff0c;槿花一日自为荣。 > 目标&#xff1a;了解什么是子网掩码&#xff0c;并且能熟练掌握子网掩码的相关计算。 > 毒鸡汤&#xff1a;有些事情&#xff0c;总是不明白&#xff0c;所以我不会…