1. 程式人生 > >POJ 3667 Hotel 模擬+暴力

POJ 3667 Hotel 模擬+暴力

/**
POJ 3667 Hotel 模擬+暴力
連結:http://poj.org/problem?id=3667
題意:給定長度為n初始化值為0的陣列a,每次詢問存在兩個操作;
1 x : 新添進來值為1,大小長度為x的陣列b.每次新添進去的位置為:最左邊,且能全部一次性放下的地點
也就是最左邊連續0的個數的長度得大於等於x,輸出當前賦值的起始點;
2 x d: 以x為起點長度為d的後面位置全部清為0;

分析:可用vector進行模擬,存取節點,節點表示1-->n值為0的區間,維護一個單調的vector;
對於詢問操作,直接暴力vec進行遍歷即可,並注意當前滿足條件的區間變化;
對於區間推平操作,找到最右邊的點的位置,對於左端點到當前最右的點,進行刪除,即可完成區間推平操作
也就是將多個不為0的區間化為一個區間的過程;
*/
#include<vector>
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath>
#define ll long long
using namespace std;

int n,q;

struct node {
	int l,r;
};
vector<node>vec;

int main(){
    scanf("%d %d",&n,&q);
    node tmp;tmp.l=1,tmp.r=n;
    vec.push_back(tmp);
	while(q--){
		int cas;scanf("%d",&cas);
		if(cas==1) {
			int x;scanf("%d",&x);
			int id=0,sz=vec.size();//至少存在一個,留;
			//for(int i=0;i<sz-1;i++) if((vec[i].r-vec[i].l+1)>=x) { id=i;break;}
			while((vec[id].r-vec[id].l+1)<x&&id<vec.size()-1) id++;//保證vec不能為空 方便下面的判斷;
			if((vec[id].r-vec[id].l+1)>=x){
				printf("%d\n",vec[id].l);
				vec[id].l+=x;
				if(vec[id].l>vec[id].r) vec.erase(vec.begin()+id);
			}
			else puts("0");
		}
		else {


			int x,d;scanf("%d %d",&x,&d);
			d=x+d-1;
			node tmp;tmp.l=x,tmp.r=d;
			if(vec.size()==0) vec.push_back(tmp);//全是滿的情況;
			else if(vec.size()==1){
				if(vec[0].l-1>d) vec.insert(vec.begin(),1,tmp);//記得維護vec的區間單調性(遞增);
				else if(vec[0].r<x-1) vec.push_back(tmp);
				else  vec[0].l=min(vec[0].l,x),vec[0].r=max(vec[0].r,d);
			}

			else if(vec.size()>1){
				int id=0,sz=vec.size();
				//for(int i=0;i<sz-1;i++) if(vec[i].r+1>=x) { id=i; break; }
				while((vec[id].r+1)<x&&id<vec.size()-1) id++;
				if(vec[id].l-1>d) vec.insert(vec.begin()+id,1,tmp);
				else if(vec[id].r<x-1) vec.push_back(tmp);
				else {
					vec[id].l=min(vec[id].l,x),vec[id].r=max(vec[id].r,d);
					for(int i=id;i<vec.size()-1;){
						if(vec[i+1].l-1>vec[i].r) break;
						vec[i].r=max(vec[i].r,vec[i+1].r);
						vec.erase(vec.begin()+i+1);
					}
				}
			}
		}
	}
    return 0;
}


/**
10 6
1 4
1 4
2 2 5

*/