UVa 10020 - Minimal coverage

题意是:输入几个样例,每个样例第一行输入从0开始需要覆盖的长度M,即[0,M]。之后输入覆盖的线段,求需要的线段条数最小值。

 

思路:贪心算法,具体见代码及注释。

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
using namespace std;

#define MAXN 100001

/*将输入数据进行处理,右边小于0的和左边大于M的删除
然后以Li尽量小,Ri尽量大的顺序进行排序,每次寻找到一个,
假如Li大于0,就以最小的Li当作结束继续寻找
(同理假如已经找到的Ri小于M,则继续以M为结束继续寻找)
即贪心算法*/
struct Segs{
    int l;
    int r;
};
bool cmp(Segs a,Segs b){//sort函数的_Compare部分
    return a.l < b.l;
}
class  MinCover{
    private:
        int M;//需要覆盖的长度
        Segs segs[MAXN],result[MAXN];//有效输入线段数组和结果数组
        int segNum;//有效线段数目
    public:
        void init();
        void readData();
        void process();
};
void MinCover::init(){
    memset(segs,-1,sizeof(segs));
    memset(result,-1,sizeof(result));
}
void MinCover::readData(){
    cin>>M;
    int i = 0;
    while(cin>>segs[i].l>>segs[i].r){
        if(segs[i].l==0 && segs[i].r==0)break;
        if(segs[i].l > M||segs[i].r < 0)continue;//假如左边大于M,右边小于0,不储存
        i++;
    }
    segNum = i;
}
void MinCover::process(){
    sort(segs,segs + segNum,cmp);

    int left = 0,right,isFind;
    int loop = 0,index;
    while(left < M){
        isFind = 0;
        right = left;//右端起始值和左边一致,随左端更新而更新
        for(int j = 0;j < segNum;j++){//贪心,
            if((segs[j].l <= left) && (segs[j].r > right)){//寻找到的值应小于左端,大于“右端”
                index = j;
                isFind = 1;
                right = segs[j].r;
            }
        }
        if(isFind==1){
            result[loop++] = segs[index];
            left = segs[index].r;//将找到的最大右边作为即将继续寻找的起点。
        }
        else break;
    }
    if(isFind==1){
        cout<<loop<<endl;
        for(int k = 0;k < loop;k++){
            cout<<result[k].l<<" "<<result[k].r<<endl;
        }

    }
    else
        cout<<0<<endl;
}
int main()
{
    //freopen("D:\\acm.txt","r",stdin);
    int cases;
    MinCover mincover;
    mincover.init();
    cin>>cases;
    while(cases--){
        mincover.readData();
        mincover.process();
        if(cases>0)cout<<endl;
    }
    return 0;
}

 

测试数据:请直接选中复制,点击复制按钮会导致数据缺少。

来源:http://www.algorithmist.com/index.php?title=UVa_10020

Input

7

1
-1 0
-5 -3
2 5
0 0

1
-1 0
0 1
0 0

10
-2 5
-1 6
-1 3
0 4
1 5
2 6
3 7
7 8
8 10
8 9
0 0

10
-2 5
-1 6
-1 3
0 4
1 5
2 6
3 7
8 10
8 9
0 0

10
2 5
5 3
2 3
2 5
0 0

10
0 10
0 10
0 0

6
0 2
2 4
4 6
6 8
0 0

 

Output

0

1
0 1

4
-1 6
3 7
7 8
8 10

0

0

1
0 10

3
0 2
2 4
4 6

 

posted @ 2015-05-10 00:02  小白v  阅读(184)  评论(0编辑  收藏  举报