#include <bits/stdc++.h>
using namespace std;
#define mod 1000000007
typedef long long ll;
struct JOB
{
char name[20]; //作业名字
int arrival_time; //到达时间
int start_time; //开始时间
int end_time; //结束时间
int run_time; //预计运行时间
int res_time; //剩余运行时间
int average_wait; //平均等待时间
int average_zhou; //平均周转时间
int real_start; //第一次开始的时间
int level; //优先级
int state; //状态,是否已经结束
double weight_zhou;
};
vector<JOB> process(100); //保存每个输入的作业的信息
vector<JOB> out; //保存每个时间段的作业信息
int current_time=0; //当前时间
int flag=0; //标记是否所有作业已经结束
int time_change(int x,int y) //将输入的时间转换成分钟形式
{
return x*60+y;
}
void re_change(int x) //时间格式逆转换
{
int hour;
int mint;
hour=x/60;mint=x%60;
if(mint==0) printf("%d:00 ",hour);
else printf("%d:%d ",hour,mint);
}
int get_current_process(int t) //获取当前时间t,应该是哪个进程开始执行
{
int p_id=-1;int max_lev=0;
flag=0;
int ltime=10000000;
for(int i=1;i<=process.size();i++)
{
if(process[i].state==1) flag++; //统计有多少进程结束了
if(process[i].arrival_time<=t&&process[i].state!=1) //找出到达时间小于当前时间且还没结束的进程
{
if(process[i].level>max_lev) //优先选择优先级高的
{
p_id=i;
max_lev=process[i].level;
}
if(process[i].level==max_lev) //如果优先级一致,则看谁先到
{
if(process[i].arrival_time<ltime)
{
p_id=i;
ltime=process[i].arrival_time;
}
}
}
}
return p_id;
}
int main()
{
double pjzz=0,dqpj=0;
int n;
scanf("%d",&n); //输入有多少个作业
for(int i=1;i<=n;i++) //输入信息,依次输入 名字,到底时间,运行时间,等级
{
int hour,mint,cost,lev;
scanf("%s %d:%d %d %d",process[i].name,&hour,&mint,&cost,&lev);
process[i].arrival_time=time_change(hour,mint);
process[i].run_time=cost;process[i].res_time=cost;
process[i].level=lev;
process[i].start_time=process[i].end_time=process[i].state=0; //初始化
}
current_time=process[1].arrival_time; //设置当前时间为第一个作业到达的时间
while(1)
{
int p=get_current_process(current_time); //获取当前是哪个作业可以执行
if(flag==n) break; //如果全部结束了则跳出循环
if(p==-1) current_time++; //当前时间没有进程则时间加1
else
{
if(process[p].start_time==0) //如果当前作业是第一次执行
{
process[p].start_time=current_time;
process[p].real_start=current_time;
if(out.size()!=0&&out[out.size()-1].end_time==0)
{
out[out.size()-1].end_time=current_time; //上一个作业的结束时间就是当前时间
}
out.push_back(process[p]); //将当前进程加入到输出的队列里
}
current_time++;
process[p].res_time--; //剩余时间减少
if(process[p].res_time==0) //如果执行完了
{
process[p].end_time=current_time; //赋值保存结束时间
process[p].average_zhou=current_time-process[p].arrival_time; //计算周转时间
process[p].weight_zhou=(1.0*process[p].average_zhou)/(1.0*process[p].run_time);
JOB tmp;
tmp=process[p];
if(strcmp(out[out.size()-1].name,process[p].name)==0)
{
out[out.size()-1].end_time=current_time; //如果当前进程没有被打断过,则直接修改,不用再添加。
}
else
{
tmp.start_time=out[out.size()-1].end_time; //否则就上一个作业的结束时间就是当前作业的开始时间
out.push_back(tmp); //加入到输出队列
}
process[p].state=1; //标记当前作业已经结束了
}
}
}
printf("\n调度运行过程:作业名字,作业开始时间,作业结束时间,作业等级\n");
for(auto x: out)
{
printf("%s ",x.name);
re_change(x.start_time);
re_change(x.end_time);
printf("%d\n",x.level);
}
printf("\n");
printf("调度结果:作业名字,作业开始时间,作业结束时间,作业周转周期\n");
for(int i=1;i<=n;i++)
{
printf("%s ",process[i].name);
re_change(process[i].real_start);
re_change(process[i].end_time);
printf("%d %.2f\n",process[i].average_zhou,process[i].weight_zhou);
pjzz+=1.0*process[i].average_zhou;
dqpj+=1.0*process[i].weight_zhou;
}
printf("平均周转时间、带权平均周转时间\n");
printf("%.2f %.2f\n",pjzz/(1.0*n),dqpj/(1.0*n));
return 0;
}