1.描述
给定两个整数,指定管理资源的范围。
可用选择从头分配,也可以指定ID进行分配,释放资源时需要指定ID进行释放,并将资源放入尾部(若超出范围或者指定不合适,则操作失败,什么也不执行)
初始为有序的,要求经过若干次操作后的第一个空闲资源ID。
采用队列进行模拟,并用哈希表表示资源是否可用。这里的主要困难是,如果指定ID进行分配,那么不会立即将其弹出。但如果此时释放该资源的话,会重新将该ID加入队列尾部。这样在队列中就有重复元素出现。
解决方法为:
使用两个哈希表,一个表示该资源是否可用,一个标识该资源在队列中的出现次数。
如果从头进行分配时,必须满足两个条件:资源可用,出现次数为1
可用维护一个可用资源的数量,用来应对从头分配时,空闲ID不足分配失败的场景
2.代码
#include <iostream>
#include <vector>
#include <queue>
#include <unordered_map>
using namespace std;
int main(){
int ln, rn;
cin >> ln >> rn;
queue<int> q;
unordered_map<int,int> mm; // 代表出现几次
unordered_map<int,int> mm1; // 代表是否可用
int remin_num = rn - ln + 1;
for(int i = ln; i <= rn; i++) {
q.push(i);
mm[i] = 1;
mm1[i] = 0;
}
int t;
cin >> t;
int fnum, snum;
for(int i = 0; i < t; i++) {
cin >> fnum >> snum;
if(fnum == 1) {
if(remin_num < snum)
continue;
remin_num -= snum;
int tmp = snum;
while(tmp) {
int cur = q.front();
q.pop();
if( mm1[cur] == 0 && mm[cur] == 1 ) {
mm1[cur] = 1;
tmp--;
}
mm[cur]--;
}
}else if(fnum == 2) {
if( snum >= ln && snum <= rn && mm1[snum] == 0 ) {
mm1[snum] = 1;
remin_num--;
}
}else {
if( snum >= ln && snum <= rn && mm1[snum] == 1) {
mm1[snum] = 0;
mm[snum]++;
remin_num++;
q.push(snum);
}
}
}
while(!q.empty() && (mm[q.front()] > 1 || mm1[q.front()] == 1)) {
mm[q.front()]--;
q.pop();
}
cout << q.front() << endl;
return 0;
}