时间片轮转算法 (Aizu - ALDS1_3_B:Queue)
题意:
There are n processes in a queue.
Each process has namei and timei.
The round-robin scheduling handles the processes in order.
A round-robin scheduler gives each process a quantum (a time slot) and
interrupts the process if it is not completed by then.
The process is resumed and moved to the end of the queue,
then the scheduler handles the next process in the queue.
For example, we have the following queue with the quantum of 100ms.
A(150) - B(80) - C(200) - D(200)
First, process A is handled for 100ms,
then the process is moved to the end of the queue with the remaining time (50ms).
B(80) - C(200) - D(200) - A(50)
Next, process B is handled for 80ms.
The process is completed with the time stamp of 180ms and removed from the queue.
C(200) - D(200) - A(50)
Your task is to write a program which simulates the round-robin scheduling .
输入描述:
n q
name1 time1
name2 time2
...
namen timen
In the first line the number of processes n
and the quantum q are given separated by a single space.
In the following n lines,
names and times for the n processes are given.
namei and timei are separated by a single space.
输出描述:
For each process, prints its name and the time the process finished in order.
约束:
1 ≤ n ≤ 100000
1 ≤ q ≤ 1000
1 ≤ timei ≤ 50000
1 ≤ length of namei ≤ 10
1 ≤ Sum of timei ≤ 1000000
输入样例:
5 100
p1 150
p2 80
p3 200
p4 350
p5 20
输出样例:
p2 180
p5 400
p1 450
p3 550
p4 800
这是一道关于时间片轮转调度算法的队列简单使用。
我们有5个任务,已经对应的运行时间:
系统如何处理这些任务呢?
我们可以看到,我们把任务拍成一队,从左往右依次上工作台运行。
每次我们取队头的一个元素上工作台运行,
工作台每次能运行的时间有限,这个时间即时间片大小,
那么,会造成两种情况:
①时间片>=任务需要的运行时间:
那么此时运行完之后,这个任务就结束了。
②时间片<任务需要的运行时间:
那么此时我们把任务添加到队尾,然后取下一个元素(队头元素),上工作台:
这就是时间片轮转算法的大概原理。
前人真是好聪明啊。
用上一篇的队列来写的AC代码:
#include<iostream>
using namespace std;
struct Point//任务结构点
{
string name;//任务名称
int time; //运行时间
};
const int maxn=100000+10;
Point a[maxn];
int head;//头指针
int tail;//尾指针
//进队列
void enqueue(Point x)
{
a[tail]=x;
tail=(tail+1)%maxn;
}
//出队列
Point dequeue()
{
Point x=a[head];
head=(head+1)%maxn;
return x;
}
int main()
{
freopen("in.txt","r",stdin);//重定向,记得去掉
//输入
int N,T;
cin>>N>>T;
for(int i=0; i<N; i++)
{
cin>>a[i].name>>a[i].time;
}
//计算与输出
head=0;//头指针指向第一个元素
tail=N; //尾指针指向最后一个元素+1的位置
Point temp;//临时变量,可看成 “工作台 ”上的元素
int c;//“工作台 ”工作时间
int sum=0;
while(head!=tail)
{
temp=dequeue();//取队头元素
c=min(T,temp.time);//根据时间片规则,要么是一个时间片时间,要么是任务时间
temp.time-=c;
sum+=c;//计算总时间
if(temp.time>0)//任务尚未结束,同志还需努力
{
enqueue(temp);
}
else
{
cout<<temp.name<<" "<<sum<<endl;
}
}
return 0;
}
顺带一提的是,根据约束,这里的n达到了100000,所以应该使用 scanf 和 printf 来输入输出,当然由于直接AC了,所以就没有改过来。
运行结果:
Over.