【题解】P5250 【深基17.例5】木材仓库(详解)

题目

博艾市有一个木材仓库,里面可以存储各种长度的木材,但是保证没有两个木材的长度是相同的。作为仓库负责人,你有时候会进货,有时候会出货,因此需要维护这个库存。有不超过 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;
} 

猜你喜欢

转载自blog.csdn.net/weixin_45485187/article/details/108663807