1. 程式人生 > 其它 >位元組真題:萬萬沒想到之抓捕孔連順

位元組真題:萬萬沒想到之抓捕孔連順

牛客連結:https://www.nowcoder.com/question/next?pid=16516564&qid=362290&tid=49703321

直接上程式碼,記錄下我的做題經過

 1 // 應該至少需要3個while迴圈
 2 // 第一個迴圈:固定第一個特工位置,另外兩個特工往右找
 3 // 第二個迴圈:固定第二個特工位置,如果與第一個特工保持在最大範圍內,向右招最後一個特工,否則,返回第一個迴圈第一個特工位置右移
 4 // 第三個迴圈:如果與第一個特工的位置超過最大範圍,返回第一個迴圈(不用和第二個特工位置做比較)
 5 // 結果,通過了2/10的用例,出現超時問題
 6 
 7 // 第二種優化方法:時間複雜度O(n)
8 // 第一個迴圈:固定第一個特工位置 9 // 第二個迴圈,不斷往後找第三個特工位置,直到其位置超出最大距離,根據兩個位置的索引,得到區間內元素的個數 10 // 假設元素個數為x,那麼這個區間內可選的方案數為:C(x,3) 11 // 結果,通過了2/10的用例,未出現超時問題 12 13 // 第三種方法:時間複雜度O(n) 14 // 第二種方法方向是正確的,但沒考慮仔細,比如:1 2 3 4 5 6 最大距離為4;當ridx指向6時,fidx指向4,少了2 3 6和 2 4 6的組合 15 // 看了下題解,應該固定第一個特工,其位置不斷向右滑動,這樣每個區間都是獨立的,如第一個區間一定包括1,後面的區間一定不包括1
16 // 每個區間區C(x,2) 17 #include<iostream> 18 #include<vector> 19 using namespace std; 20 21 #define MAX_VAL 99997867 22 23 long long getRes(vector<long long>init, long long k) { 24 long long res = 0; 25 long long fidx = 0, ridx=2; 26 long long len = init.size(); 27 while
(fidx < len - 2) { 28 // ridx = fidx + 2; // 後面的指標不需要往回縮了 29 while (ridx < len && (init[ridx] - init[fidx]) <= k) { 30 ridx++; 31 } 32 // ridx指向範圍區間的下一個,計算c(ridx-1-fidx,2) 33 long long tmp = ridx -1- fidx; 34 res = (res+(tmp - 1) * tmp / 2)%MAX_VAL; 35 fidx++; // 第一個特工右移 36 } 37 return res % MAX_VAL; 38 } 39 40 int main() { 41 long long d, k; 42 cin >> d >> k; 43 vector<long long> init; 44 for (long long i = 0; i < d; ++i) { 45 long long tmp; 46 cin >> tmp; 47 init.push_back(tmp); 48 } 49 long long res = getRes(init, k); 50 cout << res; 51 return 0; 52 }
心之所願,永不相忘