hdu 3413——Single CPU, multi-tasking

9 篇文章 0 订阅

题意:给出几个任务,求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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值