题意:有n天,第i天有ki件衣服选择,从中选m天,使得所选衣服的最小值和最大值差值最小。
这题我虽然过了但严格来讲我WA了,因为数据太水的原因全部取最小值也能过。标准做法应该是尺取。
尺取很久都没用过了,有点生,印象中尺取主要思想应该是这样的:两个指示位置的变量,在符合要求的情况下右方指示器向右移动,不符合的话左侧指示器向右移动。
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<map>
using namespace std;
const int N = 2e6 + 10;
int ret[N];
struct node {
int val;
int id;
}date[N];
bool cmp(node a, node b) {
return a.val < b.val;
}
int main() {
int n, m, top = 0;
scanf("%d %d", &n, &m);
for (int i = 1; i <= n; i++) {
int sum;
scanf("%d", &sum);
for (int k = 1; k <= sum; k++) {
scanf("%d", &date[++top].val);
date[top].id = i;
}
}
sort(date + 1, date + 1 + top, cmp);
int l = 1, r = 1, cnt = 0, ans = 0x3f3f3f3f;
while (true) {
while (r <= top && cnt < m) {
if (ret[date[r].id] == 0) {
cnt++;
}
ret[date[r].id]++;
if (cnt == m)break;
++r;
}
while (cnt == m && l <= r) {
if (ret[date[l].id] == 1) {
ans = min(ans, date[r].val - date[l].val);
cnt--;
}
ret[date[l].id]--;
if (cnt != m) break;
++l;
}
r++;//注意r++和l++,否则会陷入死循环
l++;
if (r >= top) break;
}
printf("%d\n", ans);
}
值得一提的是,我一开始用map来记录第i天出现的次数会T233