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;
}


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