題意:
有無窮多個小球排在一列,編號爲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;
}