日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LeetCode 2020 力扣杯全国春季编程大赛(1644/4093,前40.2%)

發(fā)布時(shí)間:2024/7/5 编程问答 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LeetCode 2020 力扣杯全国春季编程大赛(1644/4093,前40.2%) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 1. 比賽結(jié)果
    • 2. 題目解析
      • 2.1 拿硬幣 Easy
      • 2.2 傳遞信息 Esay
      • 2.3 劇情觸發(fā)時(shí)間 Medium
      • 2.4 最小跳躍次數(shù) Hard
      • 2.5 二叉樹任務(wù)調(diào)度 Hard

1. 比賽結(jié)果

前兩題比較順利,24分鐘做出來了,第3,4兩題試了好久,都顯示超時(shí),第5題沒心思看,想著第3,4題應(yīng)該能做出來的。

2. 題目解析

2.1 拿硬幣 Easy

題目鏈接
桌上有 n 堆力扣幣,每堆的數(shù)量保存在數(shù)組 coins 中。我們每次可以選擇任意一堆,拿走其中的一枚或者兩枚,求拿完所有力扣幣的最少次數(shù)。

示例 1: 輸入:[4,2,1] 輸出:4 解釋:第一堆力扣幣最少需要拿 2 次, 第二堆最少需要拿 1 次, 第三堆最少需要拿 1 次, 總共 4 次即可拿完。示例 2: 輸入:[2,3,10] 輸出:8限制: 1 <= n <= 4 1 <= coins[i] <= 10

解答:

  • 除以2,向上取整即可
class Solution { public:int minCount(vector<int>& coins) {int i, sum = 0;for(i = 0; i < coins.size(); ++i)sum += ceil(coins[i]/2.0);return sum;} };

執(zhí)行用時(shí):4 ms
內(nèi)存消耗:8.4 MB


2.2 傳遞信息 Esay

題目鏈接
小朋友 A 在和 ta 的小伙伴們玩?zhèn)餍畔⒂螒?#xff0c;游戲規(guī)則如下:

  • 有 n 名玩家,所有玩家編號(hào)分別為 0 ~ n-1,其中小朋友 A 的編號(hào)為 0
  • 每個(gè)玩家都有固定的若干個(gè)可傳信息的其他玩家(也可能沒有)。
  • 傳信息的關(guān)系是單向的(比如 A 可以向 B 傳信息,但 B 不能向 A 傳信息)。
  • 每輪信息必須需要傳遞給另一個(gè)人,且信息可重復(fù)經(jīng)過同一個(gè)人

給定總玩家數(shù) n,以及按 [玩家編號(hào),對(duì)應(yīng)可傳遞玩家編號(hào)] 關(guān)系組成的二維數(shù)組 relation。
返回信息從小 A (編號(hào) 0 ) 經(jīng)過 k 輪傳遞到編號(hào)為 n-1 的小伙伴處的方案數(shù);若不能到達(dá),返回 0。

示例 1: 輸入:n = 5, relation = [[0,2],[2,1],[3,4],[2,3],[1,4],[2,0],[0,4]], k = 3 輸出:3 解釋:信息從小 A 編號(hào) 0 處開始,經(jīng) 3 輪傳遞,到達(dá)編號(hào) 4。 共有 3 種方案,分別是 0->2->0->40->2->1->40->2->3->4。示例 2: 輸入:n = 3, relation = [[0,2],[2,1]], k = 2 輸出:0 解釋:信息不能從小 A 處經(jīng)過 2 輪傳遞到編號(hào) 2限制: 2 <= n <= 10 1 <= k <= 5 1 <= relation.length <= 90, 且 relation[i].length == 2 0 <= relation[i][0],relation[i][1] < n 且 relation[i][0] != relation[i][1]

解答:

  • 把路徑的邊插入set,方便后面快速查找
  • dp[i][j] 表示第i次傳遞到j(luò)的方案數(shù)
class Solution { public:int numWays(int n, vector<vector<int>>& relation, int k) {set<vector<int>> s;for(auto re : relation)s.insert(re);vector<vector<int>> dp(k+1,vector<int>(n,0));dp[0][0] = 1;//初始狀態(tài)for(int i = 1; i <= k; ++i)//k次傳遞{for(int j = 0; j < n; ++j){ //n個(gè)人,如果存在傳遞到這的情況if(dp[i-1][j]!=0){for(int k = 0; k < n; ++k){ //傳給下一個(gè)人,可以傳給跟自己有關(guān)系的if(s.count({j,k}))//有關(guān)系dp[i][k] += dp[i-1][j];}}}}return dp[k][n-1];} };

執(zhí)行用時(shí):8 ms
內(nèi)存消耗:7.6 MB

class Solution { //更簡潔的版本 public:int numWays(int n, vector<vector<int>>& relation, int k) {int dp[6][10]= {0};dp[0][0]=1;for(int i=0;i<k;i++)for(auto ss:relation)dp[i+1][ss[1]] += dp[i][ss[0]];return dp[k][n-1];}//參看作者:xunh };

2.3 劇情觸發(fā)時(shí)間 Medium

題目鏈接
在戰(zhàn)略游戲中,玩家往往需要發(fā)展自己的勢力來觸發(fā)各種新的劇情。
一個(gè)勢力的主要屬性有三種,分別是文明等級(jí)(C),資源儲(chǔ)備(R)以及人口數(shù)量(H)。
在游戲開始時(shí)(第 0 天),三種屬性的值均為 0。

隨著游戲進(jìn)程的進(jìn)行,每一天玩家的三種屬性都會(huì)對(duì)應(yīng)增加,我們用一個(gè)二維數(shù)組 increase 來表示每天的增加情況。
這個(gè)二維數(shù)組的每個(gè)元素是一個(gè)長度為 3 的一維數(shù)組,例如 [[1,2,1],[3,4,2]] 表示第一天三種屬性分別增加 1,2,1 而第二天分別增加 3,4,2。

所有劇情的觸發(fā)條件也用一個(gè)二維數(shù)組 requirements 表示。
這個(gè)二維數(shù)組的每個(gè)元素是一個(gè)長度為 3 的一維數(shù)組,對(duì)于某個(gè)劇情的觸發(fā)條件 c[i], r[i], h[i],如果當(dāng)前 C >= c[i] 且 R >= r[i] 且 H >= h[i] ,則劇情會(huì)被觸發(fā)。

根據(jù)所給信息,請(qǐng)計(jì)算每個(gè)劇情的觸發(fā)時(shí)間,并以一個(gè)數(shù)組返回。
如果某個(gè)劇情不會(huì)被觸發(fā),則該劇情對(duì)應(yīng)的觸發(fā)時(shí)間為 -1 。

示例 1: 輸入: increase = [[2,8,4],[2,5,0],[10,9,8]] requirements = [[2,11,3],[15,10,7],[9,17,12],[8,1,14]] 輸出: [2,-1,3,-1] 解釋: 初始時(shí),C = 0,R = 0,H = 01 天,C = 2,R = 8,H = 42 天,C = 4,R = 13,H = 4,此時(shí)觸發(fā)劇情 03 天,C = 14,R = 22,H = 12,此時(shí)觸發(fā)劇情 2 劇情 13 無法觸發(fā)。示例 2: 輸入: increase = [[0,4,5],[4,8,8],[8,6,1],[10,10,0]] requirements = [[12,11,16],[20,2,6],[9,2,6],[10,18,3],[8,14,9]] 輸出: [-1,4,3,3,3]示例 3: 輸入: increase = [[1,1,1]] requirements = [[0,0,0]] 輸出: [0]限制: 1 <= increase.length <= 10000 1 <= requirements.length <= 100000 0 <= increase[i] <= 10 0 <= requirements[i] <= 100000
  • 我的比賽錯(cuò)誤解:(1、有重復(fù)元素沒考慮,2、erase 迭代器后,迭代器失效!!)
struct cmp1 {bool operator()(const vector<int>& a, const vector<int>& b)const{if(a[0]==b[0]){if(a[1]==b[1])return a[2] < b[2];return a[1] < b[1];}return a[0] < b[0];} };class Solution { public:vector<int> getTriggerTime(vector<vector<int>>& inc, vector<vector<int>>& req) {int t = 0, n = req.size(), a = 0, b = 0, c =0;vector<int> ans(n,-1);map<vector<int>, int> m;set<vector<int>,cmp1> set1;for(int i = 0; i < n; ++i){m[req[i]]=i;set1.insert(req[i]);}vector<int> tp;auto end1 = set1.upper_bound({a,b,c});for(auto it = set1.begin(); it != end1; ++it){tp = *it;if(a>=tp[0] && b>=tp[1] && c>=tp[2]){ans[m[tp]] = t;set1.erase(tp);}}for(int i = 0; i < inc.size(); ++i){t = i+1;a += inc[i][0];b += inc[i][1];c += inc[i][2];auto end = set1.upper_bound({a,b,c});for(auto it = set1.begin(); it != end; ++it){tp = *it;if(a>=tp[0] && b>=tp[1] && c>=tp[2]){ans[m[tp]] = t;set1.erase(tp);}}}return ans;} };
  • 我的賽后正確解:m.erase(it++);//這樣做迭代器不會(huì)失效
  • 利用multimap(平衡搜索樹)有序,可以進(jìn)行二分查找
struct cmp1 //自定義排序規(guī)則 {bool operator()(const vector<int>& a, const vector<int>& b)const{if(a[0]==b[0]){if(a[1]==b[1])return a[2] < b[2];return a[1] < b[1];}return a[0] < b[0];} };class Solution { public:vector<int> getTriggerTime(vector<vector<int>>& inc, vector<vector<int>>& req) {int t = 0, n = req.size(), a = 0, b = 0, c =0;vector<int> ans(n,-1);multimap<vector<int>, int, cmp1> m;for(int i = 0; i < n; ++i)m.insert(make_pair(req[i],i));vector<int> tp;for(int i = -1; i < int(inc.size()); ++i)//注意坑,int -1 跟 size_t 比較,循環(huán)進(jìn)不去{t = i+1;if(i >=0){a += inc[i][0];b += inc[i][1];c += inc[i][2];}auto end = m.upper_bound({a,b,c});for(auto it = m.begin(); it != end; ){tp = it->first;if(a>=tp[0] && b>=tp[1] && c>=tp[2]){ans[it->second] = t;m.erase(it++);//這樣做迭代器不會(huì)失效}elseit++;}}return ans;} };

2.4 最小跳躍次數(shù) Hard

題目鏈接

為了給刷題的同學(xué)一些獎(jiǎng)勵(lì),力扣團(tuán)隊(duì)引入了一個(gè)彈簧游戲機(jī)。
游戲機(jī)由 N 個(gè)特殊彈簧排成一排,編號(hào)為 0 到 N-1。
初始有一個(gè)小球在編號(hào) 0 的彈簧處。若小球在編號(hào)為 i 的彈簧處,通過按動(dòng)彈簧,可以選擇把小球向右彈射 jump[i] 的距離,或者向左彈射到任意左側(cè)彈簧的位置。
也就是說,在編號(hào)為 i 彈簧處按動(dòng)彈簧,小球可以彈向 0 到 i-1 中任意彈簧或者 i+jump[i] 的彈簧(若 i+jump[i]>=N ,則表示小球彈出了機(jī)器)。
小球位于編號(hào) 0 處的彈簧時(shí)不能再向左彈。

為了獲得獎(jiǎng)勵(lì),你需要將小球彈出機(jī)器。
請(qǐng)求出最少需要按動(dòng)多少次彈簧,可以將小球從編號(hào) 0 彈簧彈出整個(gè)機(jī)器,即向右越過編號(hào) N-1 的彈簧。

示例 1: 輸入:jump = [2, 5, 1, 1, 1, 1] 輸出:3 解釋:小 Z 最少需要按動(dòng) 3 次彈簧, 小球依次到達(dá)的順序?yàn)?0 -> 2 -> 1 -> 6,最終小球彈出了機(jī)器。限制: 1 <= jump.length <= 10^6 1 <= jump[i] <= 10000

我的BFS超時(shí)解:
超時(shí)的例子

class Solution { public:int minJump(vector<int>& jump) {int i, j, n = jump.size(), t = 0, size,tp;set<int> set;for(i = 0; i < n; ++i)set.insert(i);queue<int> q;q.push(0);set.erase(0);while(!q.empty()){size = q.size();t++;while(size--){tp = q.front();q.pop();if(tp+jump[tp] >= n)return t;if(set.count(tp+jump[tp])){q.push(tp+jump[tp]);set.erase(tp+jump[tp]);}auto end = set.upper_bound(tp);//這個(gè)地方多了lgn的查找,用數(shù)組降到O(1)for(auto it = set.begin(); it != end; ++it){q.push(*it);set.erase(*it);}}}return t;} };
  • 改進(jìn)的BFS
class Solution { public:int minJump(vector<int>& jump) {int i, n = jump.size(), t = 0, size, tp, prevPos = 0;vector<bool> vis(n,false);vis[0] = true;queue<int> q;q.push(0);while(!q.empty()){size = q.size();t++;while(size--){tp = q.front();q.pop();if(tp+jump[tp] >= n)return t;if(!vis[tp+jump[tp]]){ //向右跳過來q.push(tp+jump[tp]);vis[tp+jump[tp]] = true;}for(i = prevPos+1; tp >0 && i < tp; ++i){ //向左位置跳if(!vis[i]){q.push(i);vis[i] = true;}}prevPos = max(prevPos,tp);//沒有這句會(huì)超時(shí)//避免重復(fù)檢查某些位置}}return t;} };

2.5 二叉樹任務(wù)調(diào)度 Hard

題目鏈接

任務(wù)調(diào)度優(yōu)化是計(jì)算機(jī)性能優(yōu)化的關(guān)鍵任務(wù)之一。在任務(wù)眾多時(shí),不同的調(diào)度策略可能會(huì)得到不同的總體執(zhí)行時(shí)間,因此尋求一個(gè)最優(yōu)的調(diào)度方案是非常有必要的。

通常任務(wù)之間是存在依賴關(guān)系的,即對(duì)于某個(gè)任務(wù),你需要先完成他的前導(dǎo)任務(wù)(如果非空),才能開始執(zhí)行該任務(wù)。
我們保證任務(wù)的依賴關(guān)系是一棵二叉樹,其中 root 為根任務(wù),root.left 和 root.right 為他的兩個(gè)前導(dǎo)任務(wù)(可能為空),root.val 為其自身的執(zhí)行時(shí)間。

在一個(gè) CPU 核執(zhí)行某個(gè)任務(wù)時(shí),我們可以在任何時(shí)刻暫停當(dāng)前任務(wù)的執(zhí)行,并保留當(dāng)前執(zhí)行進(jìn)度。在下次繼續(xù)執(zhí)行該任務(wù)時(shí),會(huì)從之前停留的進(jìn)度開始繼續(xù)執(zhí)行。暫停的時(shí)間可以不是整數(shù)。

現(xiàn)在,系統(tǒng)有兩個(gè) CPU 核,即我們可以同時(shí)執(zhí)行兩個(gè)任務(wù),但是同一個(gè)任務(wù)不能同時(shí)在兩個(gè)核上執(zhí)行。
給定這顆任務(wù)樹,請(qǐng)求出所有任務(wù)執(zhí)行完畢的最小時(shí)間。

示例 1:

輸入:root = [47, 74, 31]
輸出:121
解釋:根節(jié)點(diǎn)的左右節(jié)點(diǎn)可以并行執(zhí)行31分鐘,剩下的43+47分鐘只能串行執(zhí)行,因此總體執(zhí)行時(shí)間是121分鐘。

示例 2:

輸入:root = [15, 21, null, 24, null, 27, 26]
輸出:87

示例 3:

輸入:root = [1,3,2,null,null,4,4]
輸出:7.5

限制:
1 <= 節(jié)點(diǎn)數(shù)量 <= 1000
1 <= 單節(jié)點(diǎn)執(zhí)行時(shí)間 <= 1000


總結(jié)

以上是生活随笔為你收集整理的LeetCode 2020 力扣杯全国春季编程大赛(1644/4093,前40.2%)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。