描述
学校里有一个水房,水房里一共装有 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 ≤ n ≤ 10000,1 ≤ m ≤ 100 且 m ≤ n;
1 ≤ wi ≤ 100。
输出
输出只有一行,1 个整数,表示接水所需的总时间。
样例输入
样例 #1: 5 3 4 4 1 2 1 样例 #2: 8 4 23 71 87 32 70 93 80 76
样例输出
样例 #1: 4 样例 #2: 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个同学接水,有m个水龙头,因为每个同学的接水时间时不一样的,所以我们可以利用数组来存储每个学生的接水时间,n的范围是10000,所以开一个10005大小的数组即可
2.然后利用循环,将n个同学各自的接水时间存入数组,此时对数组开始进行数据处理
3.首先分析,如果n<=m的话,意思为水龙头是够用的,而且水龙头同时开的话,接水量最多的那个同学是用时最长的,所以接水时间,就是数组中最大的那个数
4.如果n>m的话,意思有替补学生,必须等其他学生接完水后,才可以去接水,所以我们可以设置一个书签k=m+1,来标记后面排队学生的位置,可以确定前m个学生是可以同时接水的,所以,第一个接完水的是接水量最少的那个同学,那么我们可以在数组1-m的位置找出那个最小值min,即为最快接完水的时间sum=sum+min,然后对这个m个数据进行处理,如果数字为min,那么这个学生i就是接完水的,下一个等待的学生要替补过来,即a[i]=a[k],进行赋值,并且书签往后移动,下一次就是第二个替补的学生去接水,k++,其他的学生接水量减去min,意思他们还没接完,但是已经接了min的水了,直到后面所有的排队学生都已经在水龙头面前了,那就又回到了第3步,只需要找到最大的那个值max,然后累加到计时器里即可sum=sum+max
#include<bits/stdc++.h>
using namespace std;
int a[10005];//定义一维数组存放数据
int main()
{
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];//将n个数据输入到一维数组中
int k=m+1,sum=0;
while(k<n+1)//如果k后续排队的已经都完了,结束循环
{
int min=1000000;
for(int i=1;i<=m;i++)
{
if(a[i]<min)
min=a[i];//找到最小值,意思为这轮最快接完水的
}
sum=sum+min;//计时器加上第一轮接完水所用的时间
for(int i=1;i<=m;i++)//对m个水轮头数据处理
{
if(a[i]!=min)//如果不是最快接完的
a[i]=a[i]-min;//减去接水量
else
{
a[i]=a[k];//如果是接完水的,则后面的开始排队接替
k++;//接替人数往后移
}
}
}
int max=0;//所有后续人数全部接替后
for(int i=1;i<=m;i++)//找到最大值,意思为最久接水量的同学时间用的最长
{
if(a[i]>max)
max=a[i];
}
sum=sum+max;//累加器加上最后一轮的时间
cout<<sum;
return 0;
}