2023杭电第四场 1003 Simple Set Problem

我的想法是把不同集合的数字都标成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. 当然在移动右边边界的时候就要把所属集合元素的数量给加上
 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值