当前位置:   article > 正文

Leetcode第91场双周赛_code:2468

code:2468

T1:LeetCode 2465. 不同的平均值数目

 第一题比较简单,排个序后开个哈希表存总和就行

  1. class Solution {
  2. public:
  3. int distinctAverages(vector<int>& nums) {
  4. unordered_set<int> hash;
  5. sort(nums.begin(), nums.end());
  6. for(int i = 0, j = nums.size() - 1; i < j; i ++ , j --)
  7. hash.insert(nums[i] + nums[j]);
  8. return hash.size();
  9. }
  10. };

T2:LeetCode 2466. 统计构造好字符串的方案数

 简单dp问题

f(i)就表示长度为 i 的字符串有多少个,我们可以将f(i)分为两类:

一类是以one个1结尾,那我们就只要统计f(i-one)

另一类是以zero个0结尾,同理我们就只要统计f(i - zero)

所以最后f(i) = f(i - one)+ f(i - zero)

  1. class Solution {
  2. public:
  3. int countGoodStrings(int low, int high, int zero, int one) {
  4. const int MOD = 1e9 + 7;//先定义个取模数
  5. vector<int> f(high + 1);
  6. f[0] = 1;//初始一个都没有也是个方案
  7. int res = 0;
  8. for(int i = 1; i <= high; i ++ )
  9. {
  10. if(i >= zero) f[i] = f[i - zero];
  11. if(i >= one) f[i] = (f[i] + f[i - one]) % MOD;
  12. if(i >= low) res = (res + f[i]) % MOD;
  13. }
  14. return res;
  15. }
  16. };

 T3:LeetCode 2467. 树上最大得分和路径

 无向树

先分析一下题意:

Alice不断向下的路径并不是唯一的。

我们可以发现Bob每次走的路径是唯一的,我们是可以知道Bob每次走到哪里的,那这样我们就可以预处理一下每个点Bob到达的时间,根据样例给出个图

Bob从0那一点开始走,一直往上

然后我们看看Alice是怎么走的

首先Alice从根节点下来,之后开始分叉。

可以看出Alice能得到的分值是唯一确定的,不管是往左右走,左走的话不用说,右走的话也是唯一确定的只是有了Bob的影响不好算,但也还是唯一确定的。

所以我们就可以算出Alice往左右走的分值最大的是多少,所以Alice走的路径的话就是每次取最大的儿子方向走就可以了,难点就在算Alice的分数

接下来分析一下,如何算Alice的分数

 在这里我们用At表示Alice到达的时间,Bt表示Bob到达的时间。

下面在代码中展示吧

  1. const int N = 100010, M = N * 2;
  2. int n;
  3. int h[N], w[N], e[M], ne[M], idx;
  4. int bt[N], p[N];
  5. class Solution {
  6. public:
  7. void add(int a, int b)//建立一个无向图,加边函数
  8. {
  9. e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ;
  10. }
  11. void dfs1(int u, int fa)
  12. {
  13. for(int i = h[u]; ~i; i = ne[i]){
  14. int j = e[i];
  15. if(j == fa) continue;
  16. p[j] = u;
  17. dfs1(j, u);
  18. }
  19. }
  20. int dfs2(int u, int fa, int t)
  21. {
  22. int val = 0;//权值
  23. //这里分类讨论
  24. if(bt[u] == -1 || t < bt[u]) val = w[u];
  25. else if(t == bt[u]) val = w[u] / 2;
  26. int mx = -2e9;//定义最大值
  27. for(int i = h[u]; ~i; i = ne[i])
  28. {
  29. int j = e[i];
  30. if(j == fa) continue;
  31. mx = max(mx, dfs2(j, u, t + 1));
  32. }
  33. if(mx == -2e9) mx = 0;//没有儿子,没有儿子结点
  34. return val + mx;//返回答案
  35. }
  36. int mostProfitablePath(vector<vector<int>>& edges, int bob, vector<int>& amount) {
  37. memset(h, -1, sizeof h);
  38. idx = 0;
  39. n = amount.size();
  40. for(int i = 0; i < n; i ++ ) w[i] = amount[i];//求权值
  41. for(auto& edge: edges){//加边
  42. int a = edge[0], b = edge[1];
  43. add(a, b), add(b, a);
  44. }
  45. dfs1(0, -1);//这里直接枚举每个点的父节点
  46. memset(bt, -1, sizeof bt);//每个点到达的时间都初始化成-1
  47. int t = 0;
  48. while(true)
  49. {
  50. bt[bob] = t;//每次往上走一个就 ++
  51. t ++ ;
  52. if(!bob) break;
  53. bob = p[bob];//bob要走到父节点的位置
  54. }
  55. return dfs2(0, -1, 0);
  56. }
  57. };

 T4:LeetCode 2468. 根据限制分割消息

 推公式:

  1. class Solution {
  2. public:
  3. int get(int k, int limit)
  4. {
  5. int len = to_string(k).size();
  6. int res = (limit - 3 - len) * k;
  7. int s = 0;
  8. for(int i = 1, t = 9; i < len; i ++, t *= 10)
  9. {
  10. res -= i * t;
  11. s += t;
  12. }
  13. res -= len * (k - s);
  14. return res;
  15. }
  16. vector<string> splitMessage(string message, int limit) {
  17. int n = message.size();
  18. for(int i = 1; i <= n; i ++ ){
  19. if(get(i, limit) >= n){
  20. vector<string> res;
  21. for(int j = 1, k = 0; j <= i && k < n; j ++ ){
  22. string str = "<" + to_string(j) + "/" + to_string(i) + ">";
  23. int len = min(n - k, limit - (int)str.size());
  24. res.push_back(message.substr(k, len) + str);
  25. k += len;
  26. }
  27. return res;
  28. }
  29. }
  30. return {};
  31. }
  32. };

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/855983
推荐阅读
相关标签
  

闽ICP备14008679号