国庆放假,赛后补题.
A. 设计停车系统
简单模拟.
class ParkingSystem {
public:
int b,m,s;
ParkingSystem(int big, int medium, int small) {
b=big;
m=medium;
s=small;
}
bool addCar(int carType) {
if(carType==1){
if(b){ --b;return true; }
return false;
}
else if(carType==2){
if(m){ --m;return true; }
return false;
}
else{
if(s){ --s;return true; }
return false;
}
}
};
B. 警告一小时内使用相同员工卡大于等于三次的人
简单模拟.
class Solution {
public:
int getM(string str){
int h=(str[0]-'0')*10+(str[1]-'0');
int m=(str[3]-'0')*10+(str[4]-'0');
return h*60+m;
}
unordered_map<string,vector<int>> mp;
vector<string> alertNames(vector<string>& keyName, vector<string>& keyTime) {
int n=keyName.size();
for(int i=0;i<n;++i){
mp[keyName[i]].emplace_back(getM(keyTime[i]));
}
vector<string> ans;
for(auto it=mp.begin();it!=mp.end();++it){
string key=it->first;
sort(mp[key].begin(),mp[key].end());
bool flag=false;
for(int i=0;i+2<(int)mp[key].size();++i){
if(mp[key][i]+60>=mp[key][i+2]){
flag=true;
break;
}
}
if(flag) ans.emplace_back(key);
}
sort(ans.begin(),ans.end());
return ans;
}
};
C. 给定行和列的和求可行矩阵
构造,题目明确一定存在可行解,因此从上往下从左往右依次在矩阵中填入数值,每次尽可能填入尽量大的值,也就是行约束和列约束的较小值,同时更新行列约束.
class Solution {
public:
vector<vector<int>> restoreMatrix(vector<int>& rowSum, vector<int>& colSum) {
int n=rowSum.size();
int m=colSum.size();
vector<vector<int>> g=vector<vector<int>>(n,vector<int>(m,0));
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
int Min=min(rowSum[i],colSum[j]);
g[i][j]=Min;
rowSum[i]-=Min;
colSum[j]-=Min;
}
}
return g;
}
};
D. 找到处理最多请求的服务器
线段树.
使用一个长度为 k
的线段树维护每台服务器的空闲起始时间,线段树维护区间最小值,也就是空闲起始时间的最小值. 从前向后遍历每个待处理的任务,对于某个任务 i
- 若所有服务器的空闲起始时间都大于
arrival[i]
,则任务i
被丢弃. - 否则,查询
k%i
之后的第一台满足空闲起始时间最小值小于等于arrival[i]
的服务器,如果找不到,再从0
开始找( 因为k
台服务器构成一个环).
对于 1,直接查看线段树根结点的值即可;对于 2,需要单独编写一个查询函数,递归寻找满足要求的下标.
#define node tree[id]
#define lson tree[id<<1]
#define rson tree[id<<1|1]
namespace SegTree{
const int maxn=1e5+50;
struct Tree{
int le,ri,Min;
}tree[maxn<<2];
void build(int id,int le,int ri){
node.le=le;
node.ri=ri;
node.Min=0;
if(le==ri) return;
int mid=le+ri>>1;
build(id<<1,le,mid);
build(id<<1|1,mid+1,ri);
}
void update(int id,int pos,int val){
if(node.le==node.ri){
node.Min=val;
return;
}
int mid=node.le+node.ri>>1;
if(pos<=mid) update(id<<1,pos,val);
else update(id<<1|1,pos,val);
node.Min=min(lson.Min,rson.Min);
}
//查询下标大于等于pos,且值小于等于val的第一处下标
int query(int id,int pos,int val){
if(node.Min>val) return -1;//不存在则返回-1
if(node.le==node.ri) return node.le;
int mid=node.le+node.ri>>1;
if(pos>mid) return query(id<<1|1,pos,val);//pos在右子树上,直接递归右子树
int resl=query(id<<1,pos,val);//先递归左子树,如果符合要求则返回结果
if(resl!=-1) return resl;
return query(id<<1|1,pos,val);//否则继续递归右子树
}
}
class Solution {
public:
vector<int> busiestServers(int k, vector<int>& arrival, vector<int>& load) {
SegTree::build(1,0,k-1);
int n=arrival.size(),cnt_max=0;
vector<int> cnt(k,0),ans;
for(int i=0;i<n;++i){
if(SegTree::tree[1].Min>arrival[i]) continue;
int pos=SegTree::query(1,i%k,arrival[i]);
if(pos==-1) pos=SegTree::query(1,0,arrival[i]);
cnt[pos]+=1;
cnt_max=max(cnt_max,cnt[pos]);
SegTree::update(1,pos,arrival[i]+load[i]);
}
for(int i=0;i<k;++i) if(cnt[i]==cnt_max) ans.emplace_back(i);
return ans;
}
};