[ACM]孤独的运货员

13 篇文章 0 订阅

背景

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

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

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

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

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

CART


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

任务

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

输入

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

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

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

输出

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

  测试输入帮助,input (新窗口) 期待的输出帮助,expectedoutput (新窗口) 时间限制帮助,timelimit (新窗口) 内存限制帮助,memlimit (新窗口) 额外进程帮助,nproc (新窗口)
测试用例 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秒 1024KB 0

#include <stdio.h>
#include <string.h>
#define N 70
int matrix[N][N], truck[N], usedTime, sum;
void UnLoad(int no, int storeCapacity)
{
	for (int i = truck[0]; truck[0] && i > 0; i--) //从truck数组末尾开始取出“货物”
	{
		usedTime++;
		truck[0]--;//货车中货的数量减1
		if (no == truck[i]) //当前的货物编号与货站编号相同,放入A平台
			sum--; //总货物数量减1
		else if(matrix[no][0] < storeCapacity) //当前货物编号与货站编号不同且仓库未满,应该放入B平台
			matrix[no][++matrix[no][0]] = truck[i];//把货物加入第i个货站的队尾
		else //既不能装入A平台也不能装入B平台
		{
			usedTime--;
			truck[0]++;
			break;
		}
	}
}
void Load(int no, int carCapacity)
{
	int j = matrix[no][0], i;
	for (i = 1; i <= j && truck[0] < carCapacity; i++)//从仓库队列头部取出货物加入到货车尾部
	{
		usedTime++;
		truck[++truck[0]] = matrix[no][i];
		matrix[no][0]--;
	}
	if (matrix[no][0])
		for (int k = i; k <= j; k++) //移动数组元素,把空位消去
			matrix[no][k - i + 1] = matrix[no][k];
}
void Transport(int stations, int carCapacity, int storeCapacity)
{
	int i = 1, j, k;
	while (1) //货站编号从1开始
	{
		if (truck[0] > 0 && matrix[i][0] <= storeCapacity) //判断是否可以卸货,matrix[i][0]中存放的是第i个货站中货物的数量,truck[0]存放的是货车中货物的数量
			UnLoad(i, storeCapacity);
		if (!sum) return;//如果货物数为0则直接返回
		if (truck[0] < carCapacity && matrix[i][0] > 0) //判断是否可以装货
			Load(i, carCapacity);
		usedTime += 2;
		i = (i + 1) % (stations + 1) == 0 ? 1 : (i + 1) % (stations + 1);
	}
}
int main()
{
	freopen("in.txt", "r", stdin);
	int n,stations,carCapacity,storeCapacity,testNumbers,i = 0,j,k;
	scanf("%d", &testNumbers);
	while(testNumbers--)
	{
		sum = 0, usedTime = 0, i = 1;
		scanf("%d %d %d", &stations, &carCapacity, &storeCapacity);
		while (i <= stations)
		{
			scanf("%d", &matrix[i][0]);
			sum += matrix[i][0]; //计算货物的总件数
			for (j = 1; j <= matrix[i][0]; j++)
				scanf("%d", &matrix[i][j]);
			i++;
		}
		Transport(stations, carCapacity, storeCapacity);
		printf("%d\n", usedTime);
	}
	return 0;
}


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值