区间覆盖问题

来源:互联网 发布:初中生自学编程难吗 编辑:程序博客网 时间:2024/06/06 05:31

区间覆盖问题.数轴上有n个闭区间[ai,bi],选择尽量少的区间覆盖一条指定一条线段[s,t]。

例题:https://vjudge.net/problem/UVA-10020
选择尽量少的区间覆盖[0,m]

题解:

把各个区间按照起点从小到大排序。
如果第一个区间大于0,无解。因为其他区间的起点更大,不可能覆盖到0.
预处理,去掉[0,m]区间外的区间。
每次选择起点小于start的最长区间,选择完之后更新区间。
最后需判断最后一次的start是否大于等于M,否则清空操作。

#include <bits/stdc++.h>using namespace std;const int maxn = 1e5+100;typedef long long LL;typedef pair<LL,LL> p;p seg[maxn];vector<p> vec;vector<p> ans;int M;void solve(){    int siz = vec.size();    int i;    int ll=0;    int index=-1;    int start=0;    for(i=0;i<siz;i++)    {       if(vec[i].first<=start)       {           if(vec[i].second>ll)           {ll=vec[i].second;index=i;}       }       else if(index!=-1)       {           ans.push_back(vec[index]);           start = vec[index].second;           i--;       }    }    if(index!=-1&&start<M){    ans.push_back(vec[index]);    start=vec[index].second;    }    if(start<M) ans.clear();}bool cmp(p a,p b){    return a.first<b.first;}int main(){    int T;    cin>>T;    while(T--)    {        cin>>M;        int i=0;        int l,r;        while(scanf("%d%d",&l,&r))        {            if(l==0&&r==0) break;            seg[i].first=l;            seg[i].second=r;            i++;        }        sort(seg,seg+i,cmp);        /*for(int j=0;j<i;j++)        {         cout<<seg[j].first<<" "<<seg[j].second<<endl;        }*/        if(seg[0].first>0) {cout<<0<<endl;if(T) cout<<endl;continue;}        /*预处理*/        for(int j=0;j<i;j++)        {            if(seg[j].second<0||seg[j].first>M) continue;            vec.push_back(seg[j]);        }        solve();        cout<<ans.size()<<endl;        for(int k=0;k<ans.size();k++)        {            cout<<ans[k].first<<" "<<ans[k].second<<endl;        }        vec.clear();        ans.clear();    }    return 0;}
原创粉丝点击