算法训练 接水问题(模拟simulation)

本文介绍了一个模拟多人使用多个水龙头打水的问题,并提供了一种有效的算法解决方案。该算法通过不断寻找当前打水人群中所需时间最短的人,更新所有人剩余的打水时间,再通过替补机制完成整个过程,最终计算出总时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写图片描述

思路:
1)现将题目通读一下:给你n个人,m个水龙头。这里所有人都是按顺序打水的,每人打水所需的时间都是限定好的(嘿嘿,这里可能是有些人的水壶有大号的和小号的),当打水的人中有人打好后,立即有人替补且没有时间差!让我们求所需的总时间!

2)下面分几个步骤去求总时间!!
第一:如何模拟使用水龙头打水的人的情况?(代码中用Min函数实现的) 因为每秒供水量为1,我们是可以想象用循环去不断的减一,直到某些人打完水(单元的值为0,0就表示已经打完水了)改进一下:我们可以直接找到正在打水的人中所需最少的时间,假定为temp,让正在使用水龙头打水的人都减去temp,这样就直接找到打完水的人了(单元值为0)。
第二:如何模拟替代(代码中用Replace函数实现):一开始打算通过数组单元的覆盖实现的,也就是当某人打完了我通过不断的移位来实现替代,但是想了想,如果同时出现多个人打好水那不是麻烦了嘛!还是通过循环遍历前面m(这里默认前m个人在使用水龙头)个单元的数组看哪些为0的,(设置一个int类型的变量Re用来标记待打水的人所在单元的下标,这里每替换一个Re都有自增)将待排序的人的值赋值到前面为0的单元,实现替换。
第三:当后面全部都替换完了之后,还剩最后一批正在使用水龙头的人。最后应该加上他们当中所需时间最长的(用Max函数获得)!!

这里写图片描述

#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<cmath>
#include<queue>
#include<stack>
using namespace std;
int Array1[10001];//打水的总人数
int Time=0;//总时间,初始化为0       
int Re=0;//替补人所在下标(这里替补人也是按照顺序的)
/*找出数组的最小值*/ 
void Min(int *Array,int n) {//数组的Array中前n个单元中找到最小单元的下标
    int temp=10000;//记录最小的值,初始值的时候,因为是找最小值,应该设大一点
    for (int i = 0; i < n; i++) {
        if (Array[i]<temp) { 
            temp = Array[i];
        } 
    }
    /*将正在打水的人的所需时间都减去最小的时间,打完的人(所需时间的值为0也就是Array[i]==0)进行替补*/
    for (int i = 0; i < n; i++) {
        Array[i] -= temp;
    }
    Time += temp;//中时间加上减去的时间,最后要的是总时间
}
/*替补函数(当水用完了时直接用后面的替补前面的)*/
void Replay(int *Array, int n) {
    //int temp = Min(Array, n);
    for (int i = 0; i < n; i++) {
        if (Array[i]==0) {
            Array[i] = Array[Re++];//如果为0表示后面的人可以替补了,Re此时++
            Array[Re - 1] = 0;//表示此人已经替补上去了
        }
    }
}
/*判断是否结束*/
bool End(int *Array,int n) {
    for (int i = 0; i < n; i++) {
        if (Array[i]!=0) {
            return 0;//0为不为空
        }
    }
    return 1;//返回1表示为空
}
/*找出数组中的最大值*/
int Max(int *Array, int n) {//数组的Array中前n个单元中找到最小单元的下标
    int temp = 0;//记录最小的值,初始值的时候,因为是找最小值,应该设大一点
    for (int i = 0; i < n; i++) {
        if (Array[i]>temp) {
            temp = Array[i];
        }
    }
    return temp;
}
int main(){
    int n, m;//总人数和水龙头数
        cin >> n >> m;
        for (int i = 0; i < n;i++) {
            cin >> Array1[i];
        }
        Re = m;//替代的是所在的单元是m水龙头最后一个的下一个单元
        while (Array1[n-1]!=0 && (!End(Array1,m))) {
            Min(Array1, m);
            Replay(Array1, m);
        }
        //当最后一个也替补上去后,也就是说就剩下正在用水龙头的人了,这时总时间应该是加上其中用时最长的!!
        cout << Time+ Max(Array1, n) << endl;
    return 0;
 }  
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿道学长啊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值