题意:给出几个任务,求CPU将它们运行出来的时间
思路:模拟。每次找出一个可以执行出来的任务,求出将其完成后的其他所有任务的剩余时间。再将这个任务完成的时间记录下来。因为有N个任务,所以一共循环N次。pre表示上次执行完成以后任务的起点,rec表示这一次找到的可以执行完成的任务。更新其余任务的剩余时间时,从pre到rec之间的任务要比rec到pre之间的任务多执行一次。
错误:第一次错误是找rec的时候,如果task[pre]≤1,那么rec就是pre。当时没有特殊处理这种情况导致被跳过。
第二次错误是找rec时应当找整数部分最小的,而不是剩余时间最小的。比如数据2.88 1 1.9 6.9,当剩余时间为1的执行完了以后,下一次应当是1.9执行完,如果找剩余时间最小的话就会找到2.88(此时变成1.88)。
代码如下:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iomanip>
using namespace std;
double task[105];
double ans[105];
bool vis[105];
int main()
{
// freopen("data.txt","r",stdin);
ios::sync_with_stdio(false);
int T;
cin>>T;
int kase=0;
while(T--)
{
cout<<"Case "<<++kase<<':'<<endl;
memset(vis,0,sizeof(vis));
int n;
cin>>n;
for(int i=0;i<n;++i)
{
cin>>task[i];
}
double now=0;
int pre=0;
for(int i=0;i<n;++i)
{
for(int j=pre;;++j)
{
j%=n;
if(!vis[j]){pre=j;break;}
}
pre%=n;
double minn=floor(task[pre]);
int rec=pre;
if(task[pre]>1)
for(int j=(pre+1)%n;j!=pre;++j)
{
j%=n;
if(j==pre)break;
if(vis[j])continue;
if(task[j]<=1){rec=j;break;}
if(floor(task[j])<minn)
{
minn=floor(task[j]);
rec=j;
}
}
vis[rec]=true;
if(task[rec]<=1)
{
for(int k=pre;k!=rec;++k)
{
k%=n;
if(k==rec)break;
if(vis[k])continue;
task[k]-=ceil(task[rec]);
now+=ceil(task[rec]);
}
now+=task[rec];
}
else{
for(int k=pre;k!=rec;++k)
{
k%=n;
if(k==rec)break;
if(vis[k])continue;
task[k]-=ceil(task[rec]);
now+=ceil(task[rec]);
}
for(int k=rec+1;k!=pre;++k)
{
k%=n;
if(k==pre)break;
if(vis[k])continue;
task[k]-=(ceil(task[rec])-1);
now+=(ceil(task[rec])-1);
}
now+=task[rec];
}
ans[rec]=now;
pre=rec+1;
pre%=n;
}
for(int i=0;i<n;++i)
{
cout<<setiosflags(ios::fixed)<<setprecision(2)<<ans[i]<<endl;
}
}
return 0;
}