孤独的运货员

背景

航空公司的货运飞机往返于各个国家和货物分理中心之间,分理中心的货物运送到各个国家,再将各个国家发出的货物送到分理中心。

分理中心非常庞大,每个国家都有一个自己的货运站,每个货运站有两个平台用于堆放货物。其中 A 平台用于堆放运送到该国的货物,而 B 平台堆放着其它国家的货物。各个国家的货运站排成一个环形。

平时,有货运汽车沿着环形的线路在各个国家的货运站之间运行。货运汽车的仓库是非常狭窄的,先放进去的货物只能等后放进去的货物移走之后才能搬出来。

当货运汽车到达一个站点 X 时,它首先卸货。卸货的过程是:首先查看最外面的箱子是否标记着 X 标签,如果是,代表这是运送到 X 国的货物,则放到 A 平台上,如果不是,则把该货箱放到B平台货物队列的末尾,然后处理下一箱货。当 B 平台放满或者是车被搬空,则开始装货。装货的过程是:从 B 平台货物队列的开始处装车,把车装满或把 B 平台搬空则装货结束。车子开往下一个货运站。

卸下一箱货物和装载一箱货物均需要一分钟的时间,且假设当货车从一个货运站开往另一个货运站的时间为两分钟。

每天,货车和货运飞机都这样周而复始的运行着,直到有一天因为报酬的原因,分理中心的工人开始罢工。货运飞机依然运行,但却无法运走任何货物。

任务

你是老板的心腹,平时深受老板关照。因此,你决定停止罢工,独自担当起分理的任务。现在,分理中心已经堆积了大量的货物,你决定在开始前先写程序计算一下要完成搬运需要多长的时间。

输入

对于输入部分包含几组数据,第一行是一个整数SET,表明下面有几组数据,随后便是这几组输入数据。

对于每一组输入数据,其第一行为三个整数 N、S 和 Q。其中 N(2<=N<=100) 表示环中站的个数。S(1<=S<=100) 表示货车的最大容量,即货车同时可以装载多少箱货物。而 Q(1<=Q<=100) 表示 B 平台所能放置的货物的总数,假定该系统中所有货运站 B 平台的最大容量都相同。

从第二行往后一共有 N 行,每行一的第一个数字代表该站 B 平台上货物的总数,之后的每个数字代表每箱货物运送到哪个站。

输出

对于每组输入,你需要在独立的一行中输出完成该任务所需要的时间。

 测试输入关于“测试输入”的帮助期待的输出关于“期待的输出”的帮助时间限制关于“时间限制”的帮助内存限制关于“内存限制”的帮助额外进程关于“{$a} 个额外进程”的帮助
测试用例 1以文本方式显示
  1. 2↵
  2. 5 2 3↵
  3. 3 4 5 2↵
  4. 2 1 3↵
  5. 0↵
  6. 3 3 5 1↵
  7. 1 4↵
  8. 5 2 3↵
  9. 3 4 5 2↵
  10. 2 1 3↵
  11. 0↵
  12. 3 3 5 1↵
  13. 1 4↵
以文本方式显示
  1. 72↵
  2. 72↵
1秒1024KB0
#include<stdio.h>  
#include<stdlib.h>  
  
typedef struct commodity{  
    int id;  
    struct commodity *next;  
}commodity;   
  
typedef struct platform{  
    int num;  
    commodity *front;  
    commodity *rear;  
}platform;  
  
typedef struct lorry{  
    int *top;  
    int *final;  
}lorry;  
  
int main(){  
    int n,i,j,k,amount,time=0;  
    scanf("%d",&n);  
    int N,S,Q;  
    platform *plat;  
    commodity *one,*tail,*head;  
    lorry van;  //不是指针   
      
    while(n--)  
    {  
        time=0; //时间归零   
        scanf("%d%d%d",&N,&S,&Q);  
        plat=(platform*)malloc(N*sizeof(platform));  //初始化N个平台   
        for(j=0;j<N;j++)     //遍历平台   
        {  
            scanf("%d",&amount);    //该平台货物数量   
            tail=(commodity*)malloc(sizeof(commodity));  //平台B队尾   
            tail->next=NULL;  
            plat[j].front=plat[j].rear=tail;    
            plat[j].num=0;  
            for(k=0;k<amount;k++) //遍历货物  
            {  
                one=(commodity*)malloc(sizeof(commodity));  
                tail->next=one;  
                scanf("%d",&one->id);  //加入货物   
                one->next=NULL;  
                plat[j].rear=one;  
                plat[j].num++;  
                tail=tail->next;  
            }  
            //printf("AAA %d,%d\n",j,plat[j].num);   
               
        }  
          
        van.final=(int*)malloc(S*sizeof(int)); //初始化货车   
        van.top=van.final;    //不能用->   
        int flag;  
          
        for(i=0,flag=0; ; i=++i%N)   
        {     
            //printf("%d,%d\n",i,plat[i].num);  
            while(van.top!=van.final) //车上有货物,先卸货   
            {  
                if(*(van.top-1)==i+1) //是该站点的   
                {  
                    van.top--;  //从货车栈顶取走货物装到A平台   
                    time++;  
                }  
                else   //不是该站点的   
                {  
                    if(plat[i].num<Q){ //B平台还没放满   
                        one=(commodity*)malloc(sizeof(commodity));  
                        plat[i].rear->next=one;  //放到B平台队尾   
                        one->id=*(van.top-1);  
                        van.top--;  
                        one->next=NULL;  
                        plat[i].rear=one; //新的队尾  
                        plat[i].num++;  
                        time++;  
                    }   
                    else break; //B平台放满了,走人   
                }  
                  
            }  
              
            while((van.top-van.final<S)&&(plat[i].num>0)) //车没装满,B平台还有货,再装货   
            {     
                  
                *(van.top++)=plat[i].front->next->id; //从B平台队头拿货装车  
                head=plat[i].front->next; //标记队头  
                plat[i].front->next=plat[i].front->next->next;   
                free(head); //去掉队头  
                if(plat[i].front->next==NULL)    plat[i].rear=plat[i].front;    
                plat[i].num--;  
                time++;  
                  
            }   
              
              
            for(j=0,flag=0;j<N;j++)  
            {  
                if(plat[j].num != 0) flag=1;  
            }  
              
            if((flag==0)&&(van.top==van.final))  break; //搞定   
              
            time+=2; //到下一站   
        }  
        printf("%d\n",time);  
    }  
    return 0;  
}  

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值