0
点赞
收藏
分享

微信扫一扫

进阶实验 3-3.2:银行排队问题之单窗口“夹塞”版

Gaaidou 2022-03-25 阅读 17
算法

想了一段时间,实在不知道该怎么下手… 太菜了…
只能看别人的,然后加点解释了 ┭┮﹏┭┮
看的此博主的

把一个朋友圈的映射为同一个编号。
结构体记录每个人的信息:姓名,开始,处理,属于的块号
维护两个变量:结束时间,等待时间。

每次队列循环只处理一个人 
怎么找到那个人呢? 
第一遍循环:看 在e之前 ,是否存在同一个朋友圈的,如果存在,存入队列,结束。
第二遍循环:若第一遍没有找到同一个朋友圈的,则按顺序找到第一个没有访问过的人即可 
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,j,n) for(int i=j;i<=n;i++)
const int N=1e5;
int n,m,cnt;
struct node {
	string name;
	int st,en;
	int f;
} aa[N];
int vis[N];
map<string,int>q;
double w;
int e;
int main() {
	cin>>n>>m;
	int belong=0;
	rep(i,1,m) {
		int num;
		cin>>num;
		rep(j,1,num) {
			string x;
			cin>>x;
			q[x]=i;
		}
	}
	rep(i,1,n) {
		cin>>aa[i].name>>aa[i].st>>aa[i].en;
		aa[i].en=min(aa[i].en,60);
		aa[i].f=q[aa[i].name];
	}
	queue<node>q;
	q.push(aa[1]);
	vis[1]=1;
	e=aa[1].st+aa[1].en;
	bool fla;
	while(!q.empty()) {
		fla=false;
		node temp=q.front();
		q.pop();
		cout<<temp.name<<endl;
		//	vis[temp.]
		rep(i,2,n) {
			if(vis[i]) continue;
			if(aa[i].st>e) break;
			if(aa[i].f==temp.f) {
				vis[i]=1;
				w=w+e-aa[i].st;
				e=e+aa[i].en;
				fla=true;
				q.push(aa[i]);
				break;
			}
		}
		if(!fla) { 这次没有找的朋友圈的人
			rep(i,2,n) {
				if(vis[i]) continue;
				w=w+max(0,e-aa[i].st);
				if(e<aa[i].st)
					e=aa[i].st;
				e+=aa[i].en;
				vis[i]=1;
				q.push(aa[i]);
				break;
			}
		}
	}
    printf("%.1lf",w/n);
    return 0;
}
举报

相关推荐

0 条评论