PTA 1017 Queueing at Bank 题解与收获

题链接:https://pintia.cn/problem-sets/994805342720868352/problems/994805491530579968

题目解析:该题是排队事件的模拟,应注意以下几个点

1.17:00:01(包括该时间)后直接忽略
2.注意时间段的端点,如一个人如果占用[08:00:00,08:01:00],则有人08:01:00到来,则他开始为08:01:01,等待1s
3.对于获取最早可以使用的窗口,可以使用优先队列存储窗口数据结构。
4.对到来的用户按到来时间进行排列

#include
#include
#include
#include
#include
using namespace std;

const static int MAXN=10005;
const static int MAXK=105;

struct Time{
int hh,mm,ss;

bool operator <(const Time &t)const {
	if(hh<t.hh){
		return true;
	}else if(hh==t.hh&&mm<t.mm){
		return true;
	}else if(hh==t.hh&&mm==t.mm&&ss<t.ss){
		return true;
	}else{
		return false;
	}
}

};

struct Customer{
Time atime; //到达的时间
int pt; //需要使用的时间
int wt; //等待的时间 (秒)

bool operator <(const Customer &c) const {
	if(atime<c.atime){
		return false;
	} else{
		return true;
	}
}

};

struct Window{
int t;
int index;
bool operator<(const Window &w) const {
return t>w.t;
}
};

vector cv;
int N,WK;

Time string2time(string str){
Time t;
t.hh=(str.at(0)-‘0’)*10+str.at(1)-‘0’;
t.mm=(str.at(3)-‘0’)*10+str.at(4)-‘0’;
t.ss=(str.at(6)-‘0’)*10+str.at(7)-‘0’;
return t;
}

void solve(){
int v=cv.size();
int u=min(WK,v);
priority_queue wq;
for(int i=0;i<u;i++){
Window w;
w.index=i;
w.t=cv[i].atime.hh3600+cv[i].atime.mm60+cv[i].atime.ss-83600+cv[i].pt60;
wq.push(w);
}

if(u==v)return;

for(int i=u;i<cv.size();i++){
	Window cuse=wq.top();
	wq.pop();
	
	int tt=cv[i].atime.hh*3600+cv[i].atime.mm*60+cv[i].atime.ss-8*3600;
	if(tt<cuse.t){
		cv[i].wt+=cuse.t-tt;
		cuse.t+=cv[i].pt*60;	
	}else if(tt==cuse.t){
		cv[i].wt+=1;
		cuse.t+=cv[i].pt*60+1;
	}
	else{
		cuse.t=tt+cv[i].pt*60;		
	}
	wq.push(cuse);	
}

}

void print_res(){
double res=0;
for(int i=0;i<cv.size();i++){
res+=cv[i].wt;
}
int v=cv.size();
res=res/60;
res=res/v;
cout<<setiosflags(ios::fixed)<<setprecision(1)<<res<<endl;
}

int main(){
cin>>N>>WK;
Time start=string2time(“08:00:00”);
Time end=string2time(“17:00:01”);
for(int i=0;i<N;i++){
string a;
int b;
cin>>a>>b;
Time tmp=string2time(a);
Customer c;
c.atime=tmp;
c.pt=b;
c.wt=0;
if(tmp<end){
cv.push_back©;
}
}
sort(cv.begin(),cv.end());
reverse(cv.begin(),cv.end());
for(int i=0;i<cv.size();i++){
if(cv[i].atime<start){
cv[i].wt=(start.hh3600+start.mm60+start.ss)-(cv[i].atime.hh3600+cv[i].atime.mm60+cv[i].atime.ss);
cv[i].atime=start;
}
}
solve();
print_res();
return 0;
}

对于重载运算符需要注意的点:
1.使用sort函数时和进行运算符比较的情况是相反的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值