HDU 2600 War

HDU 2600 

War

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2600

题目大意:

给出一个初始区间和n个覆盖区间。

如果所有的覆盖区间不能全部覆盖初始区间,则输出区间上没有被覆盖的最大的点。

如果初始区间被完全覆盖,则输出 “Badly!”。

 

典型的贪心,区间覆盖四个字都写到脸上了。

对于所有的覆盖区间[Ai,Bi],首先要进行排序,然后才能进行下一步操作。那么排序时要按照哪个部分进行呢? 按照计算开始的顺序,如果从起始点开始,就按照左端点排序。如果从终点开始,就按照右端点排序。

我比较喜欢顺其自然,接下来的讨论只针对从起始点开始的情况。

当所有覆盖区间排序完毕,接下来我们就要思考:如何获得未被覆盖的区间最大值。

这里提供一种思路,首先,我们要判断起始区间是否被完全覆盖。

因为覆盖区间都按照起始点进行排序,那么我们只需要进行覆盖计算,就能知道覆盖区域大小。

 

那么就分为这么几种情况:

因为只讨论最大的未被覆盖值,所以我们只看最后面的点。

1. 起始区间未被完全覆盖,尾端未被完全覆盖。

 

2. 起始区间未被完全覆盖,两端被覆盖,中间某处未被覆盖。

 

3. 起始区间未被完全覆盖,起始端未被完全覆盖。

 

4. 起始区间完全被覆盖。

这种情况直接可以输出 “Badly!”了。

有上面可得,我们需要同时计算两个点:最大的覆盖区间的左端点之后的点Pl,右端点之前的点Pr。然后就可以得出结果,伪代码如下:

初始化 Pl = 第一个覆盖区间的左端点 - 1;

初始化 Pr = 第一个覆盖区间的右端点 + 1;

for( 针对每个覆盖区间 )
{
    if ( 该覆盖区间不和上一个重合 )
    {
        更新Pl的值
    }
    if( 该端点的右端点比pr大 )
    {
        更新Pr的值
    }
} 
if( Pr 小于等于 初始区间的最右端点 )
{
     输出Pr。
}else if( Pl 大于等于 初始区间的最左端点 )
{
    输出Pl。
}else
{
    输出 “Badly!”
}


ac代码:


#include 
#include 
#include 

using namespace std;

#define NUM 105

#define INF 0XFFFFFFFF

struct Node
{
    int start;
    int end;
};

int cmp(Node a,Node b)
{
    if(a.start != b.start){
        return a.start < b.start;
    }

    return a.end > b.end;
}

Node map;
Node arr[NUM];

int main()
{
    int N = 0;
    while(cin>>N){
        cin>>map.start>>map.end;

        char name_tmp[1024];
        for(int i = 1; i <= N; i++){
            cin>>arr[i].start>>arr[i].end;
            cin.getline(name_tmp, 1024);
        }

        sort(arr+1, arr+N+1, cmp);

        int pos_min = -INF;
        if(arr[1].start > map.start){
            pos_min = arr[1].start -1;
        }
        int pos_max = arr[1].end;

        for(int i = 2; i <= N; i++){
            if(arr[i].start > arr[i-1].end + 1){///´æÔÚδ¸²¸ÇµÄ¿Õ¼ä
                pos_min = arr[i].start -1;
            }

            if(arr[i].end > pos_max){
                pos_max = arr[i].end;
            }
        }

        if(pos_max < map.end){
            cout<



你可能感兴趣的:(日常比赛)