蓝桥杯VIP试题 算法训练 接水问题 C/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个水龙头下接水的人,给定判断当一个人接水完成后马上换下一个,这个排列不是从小到大的排列,所以你不知道到底是m个接水的人当中哪一个先接完水换下一个,所以每次都会进行一次判定,谁接水完成了之后就让下一个人换上,至于哪一个人我们可以用一个变量来记录,比如上述题目中的例子,记录前4个人打水时,变量的值为4,意味全面有四个打水,当有一个打完时,变量加一变成5,依次打完加一,直到完成为止,但是本题一个一个判断会运行超时,所以为了缩短时间我加了两次判定,上面例子中四个数23、71、87、32,最小值为23,所以直接四个数减去最小数23,这样就可以不用一秒一秒依次计算了,节省了很多时间,而最后的时候,这个例子是四个水龙头,当剩下的人数小于或者等于4,选取最大的那个数,用当前时间加上这个数就是剩下所用的时间了,快捷很多,可以解决运行超时问题(废话不多,看代码)。

代码如下:

#include<iostream>
#include<algorithm>
using namespace std;
main(){
	int i,j=0,n,m,a[11005],k=0,sum=0,b[305],k1=0,sum1=-1,min1=20005;
	cin>>n>>m;
	for(i=0;i<n;i++){
		cin>>a[i];
	}
	for(i=0;i<m;i++){
		b[i]=j;
		j++;
	}
	while(k<n){
		k=0;k1=0;min1=20005;   //题中没有出现超过上千的数,所以这个min1还是设置的大了点,可以减少
		for(i=0;i<m;i++){
			min1=min(min1,a[b[i]]);
		}
		for(i=0;i<m;i++){
			a[b[i]]-=min1;
		}
		sum+=min1;
		for(i=0;i<m;i++){
			if(a[b[i]]==0){
				b[i]=j;
				j++;   //这里给值可能会出现大于人数的值,所以如果给定判断条件小于n,最后判断的时候j就不用大于n了,可以等于
			}
		}
		for(i=0;i<n;i++){
			if(a[i]==0){
				k++;
			}
			else{
				k1++;
			}
		}
		sum1=-1;
		if(j>=n && k1<=m){   //这个取大于和小于主要是怕有些相等直接消掉很多,剩下的数可能就少于水龙头个数了,会导致题目出错
			for(i=0;i<m;i++){
				sum1=max(sum1,a[b[i]]);
			}
			break;
		}
	}
	cout<<sum+sum1;
}
发布了63 篇原创文章 · 获赞 64 · 访问量 3561

猜你喜欢

转载自blog.csdn.net/weixin_45269353/article/details/104712416