试题 算法训练 接水问题(蓝桥杯C++)

资源限制
时间限制:1.0s 内存限制:64.0MB
问题描述
  学校里有一个水房,水房里一共装有m 个龙头可供同学们打开水,每个龙头每秒钟的 供水量相等,均为1。 现在有n 名同学准备接水,他们的初始接水顺序已经确定。将这些同学按接水顺序从1 到n 编号,i 号同学的接水量为wi。接水开始时,1 到m 号同学各占一个水龙头,并同时打 开水龙头接水。当其中某名同学j 完成其接水量要求wj 后,下一名排队等候接水的同学k 马上接替j 同学的位置开始接水。这个换人的过程是瞬间完成的,且没有任何水的浪费。即 j 同学第x 秒结束时完成接水,则k 同学第x+1 秒立刻开始接水。若当前接水人数n’不足m, 则只有n’个龙头供水,其它m−n’个龙头关闭。 现在给出n 名同学的接水量,按照上述接水规则,问所有同学都接完水需要多少秒。
输入格式
  第1 行2 个整数n 和m,用一个空格隔开,分别表示接水人数和龙头个数。 第2 行n 个整数w1、w2、……、wn,每两个整数之间用一个空格隔开,wi 表示i 号同 学的接水量。
输出格式
  输出只有一行,1 个整数,表示接水所需的总时间。
样例输入
5 3
4 4 1 2 1
样例输出
4
样例输入
8 4
23 71 87 32 70 93 80 76
样例输出
163
输入输出样例 1 说明
  第1 秒,3 人接水。第1 秒结束时,1、2、3 号同学每人的已接水量为1,3 号同学接完
  水,4 号同学接替3 号同学开始接水。
  第2 秒,3 人接水。第2 秒结束时,1、2 号同学每人的已接水量为2,4 号同学的已接
  水量为1。
  第3 秒,3 人接水。第3 秒结束时,1、2 号同学每人的已接水量为3,4 号同学的已接
  水量为2。4 号同学接完水,5 号同学接替4 号同学开始接水。
  第4 秒,3 人接水。第4 秒结束时,1、2 号同学每人的已接水量为4,5 号同学的已接
  水量为1。1、2、5 号同学接完水,即所有人完成接水。
  总接水时间为4 秒。
数据规模和约定
  1 ≤ n ≤ 10000,1 ≤m≤ 100 且m≤ n;
  1 ≤ wi ≤ 100。

思路分析:
当人数小于或等于水龙头个数时,每个人都能分到水龙头,则不需要排队,总用时时间等于打水时间最长的那个同学的用时。
当人数大于水龙头个数时,需要排队,最先打完水的同学让出给下一个同学打水,不妨新建一个数组,数组的每个元素代表每个水龙头的总用时长。现将前m个元素存入新数组中。再按(有小到大排序;下一个数组元素再加到新数组最小值上)进行循环,直到所有元素加到新数组中。最后循环结束,按有小到大排序,输出最大值即为结果。

#include<bits/stdc++.h>
using namespace std;
int main()
{   int temp;//用于数值调换的中间量 
	int n;//打水的人数
	int m;//水龙头的个数
	cin>>n>>m;
	int s[n];//定义数组,存放每个人打水的量,由于打水速度为1,大水量与打水时间数值相等 
	for(int i=0;i<n;i++)
	{
		cin>>s[i];      //依次输入每个人打水的量 
	}
	if(n<=m)//当打水人数小于或等于水龙头的个数时,不用排队,每个人同时开始打水 
	{
		for (int i = 0; i < n-1; i++)//排序 
		{
			for(int j=i+1;j<n;j++)
			{
				if(s[i]>s[j])
				{
					temp=s[i];
					s[i]=s[j];
					s[j]=temp;	
				}
			}
		}
		cout<<s[n-1];//输出最长时间 
	} 
	else//当打水人数小大于水龙头的个数时,要排队 
	{	int t=m;
	    int p[m];//新建数组p,存放每个水龙头的使用时间 
	
		for(int i=0;i<m;i++)//将s数组的前m个值存入新数组p中 
		{
		p[i]=s[i];	
		}
	    while(t<n)  //当t<n时,有人还没打水 
	    {for (int i = 0; i < m-1; i++)//排序 
		{
			for(int j=i+1;j<m;j++)
			{
				if(p[i]>p[j])
				{
					temp=p[i];
					p[i]=p[j];
					p[j]=temp;	
				}
			}
		}
		p[0]=p[0]+s[t++] ;//p[0]是最小值,代表最先空余的水龙头 
	    }
	    for (int i = 0; i < m-1; i++)//排序 
		{
			for(int j=i+1;j<m;j++)
			{
				if(p[i]>p[j])
				{
					temp=p[i];
					p[i]=p[j];
					p[j]=temp;	
				}
			}
		}
		cout<<p[m-1];//输出总用时最长的水龙头的用时,即为接水所需的总时间 	
	} 
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值