我的想法是把不同集合的数字都标成pair前面是数子,后面是所属的集合,然后所有的数一起排序
- 找一个区间使得所有的集合的数字都出现
- 在这样的区间中去找MAX-MIN最小的那个区间
题解:和我想的差不多,其实我就是不晓得要怎么去移动这两个边界去满足所有的条件
#include<bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
#define MAXK 1000010
#define endl '\n'
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
int t,k,buc[MAXK];
vector<P>vec;
void solve(int ans=2e9,int cnt=0){
cin>>k;
for(int i=1,siz;i<=k;i++){
cin>>siz;
for(int j=1,x;j<=siz;j++){
cin>>x;
vec.push_back(P(x,i));
}
}
sort(vec.begin(), vec.end());
for(int i=0,j=0;i<vec.size();i++){
cnt += (++buc[vec[i].second]==1);
for(;j<i&&buc[vec[j].second]>1;j++)
buc[vec[j].second]--;
if(cnt==k)ans = min(ans, vec[i].first-vec[j].first);
}
cout<<ans<<endl;
vec.clear();
fill(buc+1, buc+k+1, 0);
return;
}
r=i ,l=j
能移动j的条件就是`buc[vec[j].second]>1`意思是保证所有的集合的数字都要有所出现
- 为什么是这样取数呢?
- 怎么保证这个的正确性呢?
我自己思考以后是这样想的,根据题目意思这个d=max(这个集合)-min(这个集合)
1. 首先要满足这个构造的集合包含所有集合的元素
2. 要让这个d最小,那么就要让max和min之间最小,也就是这个集合的跨度在满足(1)的条件下尽量的小
3. 所以在满足(1)以后,如果左边界所属的元素的集合元素在这个构造的集合中的数量多于1那么为了满足min-d的需求就得移动左边边界
4. 当然在移动右边边界的时候就要把所属集合元素的数量给加上