接水问题(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 个整数,表示接水所需的总时间。

样例输入

Sample Input1:
5 3
4 4 1 2 1

Sample Input2:
8 4
23 71 87 32 70 93 80 76

样例输出

Sample Output1:
4

Sample Output2:
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。

算法思路:先让供水量最低的水龙头供完水,注意水龙头供水量最低的那个供完水后,总时长+=需水量/单位供水量(本题接水量就为时长),再检查是否有水龙头空着和是否有人在排队,若有水龙头空着且当还有人在排队,则换人上去,继续让水龙头供水,直到没有一个水龙头在供水。

#define _CRT_SECURE_NO_WARNINGS 

#include <stdio.h>
#include <stdlib.h>
#include "string.h"
#include "math.h"
#include "malloc.h"

 
typedef struct STU{
	int id;
	int wei;
};

int GetMinSec(int *a,int m){//返回水龙头供应最低的序号
	int i = 0;
	int min = 101;
	int temp = 1;
	for (i = 1; i <= m; i++){
		if (min > a[i]&&a[i]){
			min = a[i];
			temp = i;
		}
	}

	 
	return temp;//返回最低供水量的水龙头编号

}
void Update(int *p, int m,int min){
	int i = 1;
	for (i = 1; i <= m; i++){
		if (p[i]){
			p[i] -= min;//每个学生的剩余的用水量
		}
	}



}
int  end(int *p, int m){
	int i = 1;
	for (i = 1; i <= m; i++)
	{
		if (p[i]){
			return 1;
		}
	}
	return 0;


}
int isEmpty(int *p, int m){//判断是否有水龙头空着


	int i = 1;

	 
	for (i = 1; i <= m; i++){
		if (!p[i]){
			return i;//返回空水龙头的编号
		}
	}
	return 0;//没有水龙头空着

}
int main(){

	int stu[10001];
	int n = 0;//学生总数
 
	int m = 0;//水龙头总数
	int currentId = 0;
	int time = 0;
	scanf("%d%d", &n,&m);
	int i = 0;
	for (i = 1; i <= n; i++){
		scanf("%d", &stu[i]);//记录每个学生的用水量
	}
	int *p = (int*)malloc(sizeof(int)*(m+1));
	for (i = 1; i <= m; i++){
		p[i] = stu[i];//初始化每个水龙头对于一个学生
	}
	currentId = m;

	while (end(p,m)){
		 
		int temp = GetMinSec(p, m);//检测最低用水供应的水龙头

		time += p[temp];//最低需求用水量所需时间
		Update(p,m,p[temp]);//更新水龙头供应数组
		int currentWaterId = isEmpty(p, m);
		while (currentWaterId&&currentId!=n){//判断供应最低的水龙头放完水后水龙头有空位且有人排队
			int temp = currentWaterId;
			p[temp] = stu[++currentId];
			currentWaterId = isEmpty(p, m);

		}
	}
	free(p);
	printf("%d\n", time);



}
	 

posted @   昊月光华  阅读(31)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示