题目
博艾市有一个木材仓库,里面可以存储各种长度的木材,但是保证没有两个木材的长度是相同的。作为仓库负责人,你有时候会进货,有时候会出货,因此需要维护这个库存。有不超过 100000 条的操作:
进货,格式1 Length:在仓库中放入一根长度为 Length(不超过 10^9 ) 的木材。如果已经有相同长度的木材那么输出Already Exist。
出货,格式2 Length:从仓库中取出长度为 Length 的木材。如果没有刚好长度的木材,取出仓库中存在的和要求长度最接近的木材。如果有多根木材符合要求,取出比较短的一根。输出取出的木材长度。如果仓库是空的,输出Empty。
输入输出样例
输入
7
1 1
1 5
1 3
2 3
2 3
2 3
2 3
输出
3
1
5
Empty
思路
用map来做
因为保证没有两个木材的长度是相同的,而且木头的长度最大已经到了10^9,不能用普通数组,可以用map来映射,map[a]就表示长度为a的木头是否存在
代码
#include<bits/stdc++.h>
using namespace std;
int n,a,b;
map <int,int> m; //m[b]表示长度为b的木材存不存在
int main()
{
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%d%d",&a,&b);
if (a==1) //存入木材
{
if (m.count(b)==false) m[b]=1; //存入长度为b的木材
else cout<<"Already Exist"<<endl; //长度为b的木材已经存在了,输出
}
else if (a==2) //取出木材
{
if (m.empty()==true) cout<<"Empty"<<endl; //仓库里一根木材也不剩了
else if (m.count(b)==true)//仓库里有刚好符合长度的木材
{
cout<<b<<endl; //直接输出长度b
m.erase(b); //不要忘记清楚已经取出的木材
}
else //要查找长度相近的木材了
{
m[b]=1; //假设长度为b的木头是存在的,把他放进仓库(方便寻找指针)
map <int,int>::iterator it1; //迭代器,it相当于指针
map <int,int>::iterator it2; //用两个指针,方便下面x与y的比较
it1=m.find(b); //it1现在指向长度为b的木材的指针
it2=it1;
it2++; //it2要++,表示b后面的木头
if (it1==m.begin()) //如果把长度为b的木头放进仓库后,b是长度最小的木头,就不用往左寻找比它短的木头了
{
cout<<(++it1)->first<<endl; //直接输出后面比它长一点的木头,因为木头长度是存在it->first中的,it->second存的是该木头是否存在
m.erase(it1); //毁尸灭迹(逃)
}
else if (it2==m.end()) //如果把长度为b的木头放进仓库后,b是长度最长的木头,就不用往右寻找比它长的木头了
//这里本人有个疑惑,这里的it2不是已经++了吗,就表示的是b后面的木头,可是如果b已经是最长的话,为什么不是it1(b的位置)是尾巴呢?望大佬指点
//我是看一位博主这样写的,如果这里是it1,就过不了
{
cout<<(--it1)->first<<endl; //直接输出前面比它短一点的木头
m.erase(it1); //毁尸灭迹(逃)
}
else
{
int x=b-((--it1)->first); //x等于b左边木头与b的长度差
int y=(it2->first)-b; //y等于b右边木头与b的长度差
if (x<=y) cout<<it1->first<<endl,m.erase(it1);//左边的木头更合适
else cout<<it2->first<<endl,m.erase(it2);//右边的木头更合适
}
m.erase(b); //别忘了把刚刚放进去的b给拿出来
}
}
}
return 0;
}