hdu 1199 Color the Ball vector使用

题意:

有无穷多个小球排在一列,编号为1~infinite,然后为这些小球涂色,刚开始时小球都是黑色的,每次给a~b编号的小球涂黑色或者白色,之后统计连续白色小球最长的小球开始编号和结束编号,如果存在多个,输出编号小的那个,如果不存在白色小球序列,则输出Oh, my god

解题:

每次输入,判断是白色还是黑色,如果是白色,直接加入队列,如果是黑色,则与队列中的序列进行比较,如果当前的涂黑序列能够分裂队列中的序列为多个白色,那么就将其分裂,并将分裂的结果加入队列,直到处理完毕。

处理完之后按照结束位置从小到大的顺序对该队列进行排序,之后循环合并相邻的序列为一个大的序列,直到不能再合并。最后求出最大序列。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

class Segment
{
public:
    int startNum;
    int endNum;

    Segment(int startNum, int endNum):startNum(startNum), endNum(endNum){}
    Segment(){}
    ~Segment(){}
};

bool cmp(Segment a, Segment b)
{
    if (a.endNum != b.endNum)return a.endNum < b.endNum;
    return a.startNum < b.startNum;
}

vector <Segment > segments;

void blackSegment(const Segment &sgmt)
{
    vector<Segment >::iterator it;
    int n = (int)segments.size();
    for (int i = 0; i < n; ++i){
        Segment tmp = segments[i];
        if (tmp.startNum > sgmt.endNum || tmp.endNum < sgmt.startNum)continue;//黑不在该区间内
        if (tmp.startNum >= sgmt.startNum && tmp.endNum <= sgmt.endNum){//该区间在黑内
            it = segments.begin()+i;
            segments.erase(it);
            n--, i--;
            continue;
        }
        if (tmp.startNum < sgmt.startNum){//该区间左侧有没被涂黑的球
            segments.push_back(Segment(tmp.startNum, sgmt.startNum-1));
        }
        if (tmp.endNum > sgmt.endNum){//该区间右侧有没被涂黑的球
            segments.push_back(Segment(sgmt.endNum+1, tmp.endNum));
        }
        it = segments.begin()+i;
        segments.erase(it);
        n--, i--;
        //--------------------DebugS--------------------
        //cout << "IN:size->" << segments.size() << endl;
        //--------------------DebugE--------------------
    }
}

//--------------------DebugS--------------------
ostream & operator<<(ostream&out, const vector<Segment > & sgmt)
{
    out << "size:" << sgmt.size() << endl;
    for (int i = 0; i < (int)sgmt.size(); ++i){
        const Segment &tmp = sgmt[i];
        out << "(" << tmp.startNum << "," << tmp.endNum << ") ";
    }
    return out;
}
//--------------------DebugE--------------------

//合并区间
void mergeSegment()
{
    if (segments.size() <= 1)return ;
    int flag = true;
    while (flag){
        int n = segments.size();
        vector<Segment >::iterator it;
        flag = false;
        for (int i = 1; i < n; ++i){
            if (segments[i-1].endNum+1 >= segments[i].startNum){
                segments[i-1].endNum = segments[i].endNum;
                if (segments[i-1].startNum > segments[i].startNum)segments[i-1].startNum = segments[i].startNum;
                it = segments.begin()+i;
                segments.erase(it);
                n--, i--;
                flag = true;
            }
        }
    }
}

//计算结果
void getAnswer()
{
    if (segments.size() == 0){
        printf ("Oh, my god\n");
        return ;
    }
    int maxWhiteIndex = 0, maxWhiteLen = segments[0].endNum-segments[0].startNum;
    for (int i = 1; i < (int)segments.size(); ++i){
        int len = segments[i].endNum - segments[i].startNum;
        if (maxWhiteLen < len){
            maxWhiteIndex = i;
            maxWhiteLen = len;
        }
    }
    printf ("%d %d\n", segments[maxWhiteIndex].startNum, segments[maxWhiteIndex].endNum);
}

int main()
{
    int n, a, b;
    char c;
    while (scanf ("%d", &n)!=EOF){
        while (!segments.empty())segments.clear();
        while (n--){
            scanf ("%d%d %c", &a, &b, &c);
            if (a > b)swap(a, b);
            if (c == 'w')segments.push_back(Segment(a, b));
            else {
                blackSegment(Segment(a, b));
            }
            //--------------------DebugS--------------------
            //cout << segments << endl;
            //--------------------DebugE--------------------
        }
        sort(segments.begin(), segments.end(), cmp);
        //--------------------DebugS--------------------
        //cout << "After sort: " << segments << endl;
        //--------------------DebugE--------------------
        mergeSegment();
        //--------------------DebugS--------------------
        //cout << "After merge: " << segments << endl;
        //--------------------DebugE--------------------
        getAnswer();
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章