思路: 应该尽量找到最小的最大和最大的最小。 将所有衣服按由大到小排序。
维护一个区间,当这个区间中有m个不一样的id时就更新一次最小值,第一个指针往后移动一位。
还是很好理解。 代码有些注释
代码:
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#include<bits/stdc++.h>
#define int long long
#define sc scanf
#define pf printf
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned long long LL;
const int INF = 0x3f3f3f3f;
const double eps = 1e-4;
const int mod = 1e9+7;
const int N = 2000010;
int n,m,cnt;
struct Node{
int x,id;
bool operator <(const Node&T)const{//与直接写cmp函数一样的
return x < T.x;
}
}node[N];
int book[N];
signed main(){
IOS;
#ifdef ddgo
freopen("C:/Users/asus/Desktop/ddgoin.txt","r",stdin);
#endif
cin>>n>>m;
for(int i=1;i<=n;i++){
int len,a; cin>>len;
while(len --) cin>>a,node[cnt++] = {a,i};
}
sort(node,node+cnt);//排序
int day_sum = 0,mi = INF;
int pos_i = 0,pos_j = 0;
while(pos_j < cnt){//尺取法,while,for一样实现
int x = node[pos_j].x,id = node[pos_j].id;
if(!book[id]) day_sum ++;
book[id] ++;
while(day_sum == m){//选的天数够了,更新最小值,起点不断往后移动。
mi = min(mi,x-node[pos_i].x);
if(-- book[node[pos_i].id] == 0) day_sum --;
pos_i ++;
}
pos_j ++;
}
cout<<mi<<endl;
return 0;
}