1. 程式人生 > 實用技巧 >牛客多校(2020第九場)F Groundhog Looking Dowdy

牛客多校(2020第九場)F Groundhog Looking Dowdy

輸入

4 3
1 3
2 8 6
1 2
3 1 7 5

輸出

2

說明

Apple will pay attention to Groundhog's clothes on day 1, 3, and 4 ,Groundhog will wear clothes with dowdiness of 3, 2, and 1 on day 1, 3, and 4,and the difference is 2.

備註:

題解:

 題目大意:給出 n 天,每天可以有數件衣服可以選擇,但每天只能選擇一件衣服穿,每件衣服都有權值,現在需要挑出 m 天的衣服,使得最大值與最小值之差最小

 思路:首先我們可以把它存入一個數組,並根據它們的權值排序,然後列舉左端點,使用尺取法確定右端點, 由於已經排序,那麼答案維護一下右端點權值 - 左端點權值即可

尺取法的精髓在於在時間複雜度為O(n)的情況下,枚舉出你所需要的東西,所以列舉的每一個點都需要坐處理,如果當初用不到便儲存起來
 1 #include<iostream>
 2 #include<algorithm>
 3 #include<set>
 4 #include<vector>
 5 #include<cstring>
 6 #include<unordered_map>
 7
#include<cstdio> 8 #include<queue> 9 using namespace std; 10 11 #define P pair<int, int> 12 const int N = 1e6 + 5; 13 14 vector <P> clo; 15 int cnt[N]; 16 17 bool cmp(P a, P b) { 18 return a.second < b.second; 19 } 20 21 int main() { 22 int n, m; 23 scanf("
%d %d", &n, &m); 24 25 for (int i = 1; i <= n; i++) { 26 int k; 27 scanf("%d", &k); 28 while(k--) { 29 int val; 30 scanf("%d", &val); 31 clo.emplace_back(i, val); //pair輸入 32 } 33 } 34 sort(clo.begin(), clo.end(), cmp); 35 36 //尺取 37 int r = 0, now = 0, ans = 0x3f3f3f3f;//now用來統計不同的天數有幾個 38 memset(cnt, 0, sizeof(cnt)); //記錄遍歷過的每天的衣服的數量 39 for (int l = 0; l < clo.size(); l++) { 40 while (now < m && r < clo.size()) { 41 if (cnt[clo[r].first] == 0) { 42 now++; //如果這一天的衣服第一次出現,天數加1 43 } 44 cnt[clo[r].first]++; 45 r++; 46 } 47 48 if (now == m) { 49 ans = min(ans, clo[r-1].second - clo[l].second); 50 } 51 cnt[clo[l].first]--; 52 if (cnt[clo[l].first] == 0) { 53 now--; 54 } 55 } 56 57 printf("%d\n", ans); 58 }