题目: POJ 3667 Hotel
给个链接,自己去看。
大意也懒得说。
分析思路:
用 pair 加 set 。pair 装空房首位置数量。set排序加搜索位置。
pair.first 代表位置,pair.second 代表数量。
考虑到可能会出现一样的空位(其实不大可能)。用multiset,允许出现重复字符。给你们链接你们可以去看。(链接)
首先丢进去一个位置为1,数量为房间总数的pair。
#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
typedef pair<int,int> P;//习惯P表示pair
int main()
{
multiset<P>::iterator it;
multiset<P>::iterator its;
multiset<P>::iterator itss;
P p;
int a,b;
int d,d1,d2;
int i=1;
cin>>a>>b;
{
multiset<P> z;
p.first=1,p.second=a;
z.insert(p);
然后,查找。
while(b--)
{
scanf("%d",&d);
if(d==1)
{
scanf("%d",&d1);
d2=0;//用个标志,判断是否找得到。
it=z.begin();
for(; it!=z.end(); it++)
{
if(it->second>=d1)
{
d2=1;//找到了。
break;
}
}
if(d2==0)
cout<<'0'<<endl;//找不到。
else
{
cout<<it->first<<endl;//找到了要处理一下。
p.first=it->first+d1;
p.second=it->second-d1;
z.erase(it);
if(p.second!=0&&p.first<=a)
z.insert(p);
}
}
然后,pair合并(空房间合并)
这个地方很麻烦。
要考虑很多。
但我自己的代码写的太多了,后来发现没有必要判断是否为end()。但懒得改了,你们可以试着去掉判断end()。
先给代码然后分析。
else if(d==2)
{
scanf("%d%d",&d1,&d2);
p.first=d1;
p.second=d2;
it=z.lower_bound(p);
its=it;
itss=it;
if(it==z.end())
{
if((d1+d2-1)>=a)
{
p.second=a-d1+1;
}
if(it==z.begin());
else
{
it--;
if((it->first+it->second)>=p.first)
{
p.second=max(it->second,(p.second-it->first+p.first));
p.first=it->first;
z.erase(it);
}
}
if(p.second!=0&&p.first<=a)
z.insert(p);
}
else
{
int i=1;
if(its==z.begin())
{
i=0;
}
else
{
its--;
}
while((d1+d2)>=itss->first&&itss!=z.end())
{
it=itss;
p.second=max(d2,(it->second+it->first-d1));
p.first=d1;
if((p.first+p.second-1)>=a)
p.second=a-d1+1;
itss=it;
itss++;
z.erase(it);
}
if(i&&(its->first+its->second)>=p.first)
{
it=its;
//cout<<"it->first="<<it->first<<"it->second="<<it->second<<endl;
p.second=max(it->second,(p.second-it->first+p.first));
p.first=it->first;
z.erase(it);
//cout<<"p.first="<<p.first<<"p.second="<<p.second<<endl;
}
if(p.second!=0&&p.first<=a)
z.insert(p);
}
}
}
}
return 0;
}
分析:
第一,插入的空房间可能包括或连着后面的空房间。
第二,插入的空房间可能连着前面的空房间或者被包括。
代码懒得注释。你们可以先想想。
注意:
包括后面的房间,可能不是一个房间,要循环。(这里我wa了不下五次,死不信邪交了一遍一遍又一遍。)
被前面包括,只可能有一个房间,不需要循环。
连着前面(后面)的房间只能有一个。
代码思路都给你们了。祝早日AC。
希望你们可以学点东西。
这题一般用线段树加区间合并:
我觉得线段树,我会头晕。我就想想别的办法了。
给个线段树链接。
(链接)
本文提供了一种使用pair与multiset解决POJ3667Hotel问题的方法,通过具体代码示例详细介绍了如何管理和更新空房间状态,并讨论了线段树的应用。
&spm=1001.2101.3001.5002&articleId=81260203&d=1&t=3&u=65aebfdffb7e41db8fd4232bdc033e47)
439

被折叠的 条评论
为什么被折叠?



