赞
踩
第一题比较简单,排个序后开个哈希表存总和就行
- class Solution {
- public:
- int distinctAverages(vector<int>& nums) {
- unordered_set<int> hash;
- sort(nums.begin(), nums.end());
- for(int i = 0, j = nums.size() - 1; i < j; i ++ , j --)
- hash.insert(nums[i] + nums[j]);
- return hash.size();
- }
- };
T2:LeetCode 2466. 统计构造好字符串的方案数
简单dp问题
就表示长度为
的字符串有多少个,我们可以将
分为两类:
一类是以one个1结尾,那我们就只要统计
另一类是以zero个0结尾,同理我们就只要统计
所以最后
- class Solution {
- public:
- int countGoodStrings(int low, int high, int zero, int one) {
- const int MOD = 1e9 + 7;//先定义个取模数
- vector<int> f(high + 1);
-
- f[0] = 1;//初始一个都没有也是个方案
- int res = 0;
- for(int i = 1; i <= high; i ++ )
- {
- if(i >= zero) f[i] = f[i - zero];
- if(i >= one) f[i] = (f[i] + f[i - one]) % MOD;
- if(i >= low) res = (res + f[i]) % MOD;
- }
- return res;
- }
- };

无向树
先分析一下题意:
Alice不断向下的路径并不是唯一的。
我们可以发现Bob每次走的路径是唯一的,我们是可以知道Bob每次走到哪里的,那这样我们就可以预处理一下每个点Bob到达的时间,根据样例给出个图
Bob从0那一点开始走,一直往上
然后我们看看Alice是怎么走的
首先Alice从根节点下来,之后开始分叉。
可以看出Alice能得到的分值是唯一确定的,不管是往左右走,左走的话不用说,右走的话也是唯一确定的只是有了Bob的影响不好算,但也还是唯一确定的。
所以我们就可以算出Alice往左右走的分值最大的是多少,所以Alice走的路径的话就是每次取最大的儿子方向走就可以了,难点就在算Alice的分数
接下来分析一下,如何算Alice的分数
在这里我们用At表示Alice到达的时间,Bt表示Bob到达的时间。
下面在代码中展示吧
- const int N = 100010, M = N * 2;
-
- int n;
- int h[N], w[N], e[M], ne[M], idx;
- int bt[N], p[N];
-
- class Solution {
- public:
-
- void add(int a, int b)//建立一个无向图,加边函数
- {
- e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
- }
-
- void dfs1(int u, int fa)
- {
- for(int i = h[u]; ~i; i = ne[i]){
- int j = e[i];
- if(j == fa) continue;
- p[j] = u;
- dfs1(j, u);
- }
- }
-
- int dfs2(int u, int fa, int t)
- {
- int val = 0;//权值
- //这里分类讨论
- if(bt[u] == -1 || t < bt[u]) val = w[u];
- else if(t == bt[u]) val = w[u] / 2;
-
- int mx = -2e9;//定义最大值
- for(int i = h[u]; ~i; i = ne[i])
- {
- int j = e[i];
- if(j == fa) continue;
- mx = max(mx, dfs2(j, u, t + 1));
- }
- if(mx == -2e9) mx = 0;//没有儿子,没有儿子结点
- return val + mx;//返回答案
- }
- int mostProfitablePath(vector<vector<int>>& edges, int bob, vector<int>& amount) {
- memset(h, -1, sizeof h);
- idx = 0;
- n = amount.size();
- for(int i = 0; i < n; i ++ ) w[i] = amount[i];//求权值
- for(auto& edge: edges){//加边
- int a = edge[0], b = edge[1];
- add(a, b), add(b, a);
- }
-
- dfs1(0, -1);//这里直接枚举每个点的父节点
-
- memset(bt, -1, sizeof bt);//每个点到达的时间都初始化成-1
- int t = 0;
- while(true)
- {
- bt[bob] = t;//每次往上走一个就 ++
- t ++ ;
- if(!bob) break;
- bob = p[bob];//bob要走到父节点的位置
- }
-
- return dfs2(0, -1, 0);
- }
- };

推公式:
- class Solution {
- public:
- int get(int k, int limit)
- {
- int len = to_string(k).size();
- int res = (limit - 3 - len) * k;
- int s = 0;
- for(int i = 1, t = 9; i < len; i ++, t *= 10)
- {
- res -= i * t;
- s += t;
- }
- res -= len * (k - s);
- return res;
- }
- vector<string> splitMessage(string message, int limit) {
- int n = message.size();
- for(int i = 1; i <= n; i ++ ){
- if(get(i, limit) >= n){
- vector<string> res;
-
- for(int j = 1, k = 0; j <= i && k < n; j ++ ){
- string str = "<" + to_string(j) + "/" + to_string(i) + ">";
- int len = min(n - k, limit - (int)str.size());
- res.push_back(message.substr(k, len) + str);
- k += len;
- }
- return res;
- }
- }
- return {};
- }
- };

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。