题解分析

分析问题: 本题使用贪心+模拟,难度是普及组T2的难度,非常有代表性。

贪心算法是一种求解最优解问题的算法,它的核心思想是每一步都采取当前状态下最优的选择,从而最终得到全局最优解。它是C++重要的一种算法。

根据题意和样例数据的解释可以得到下面几点需求: 1、 5个人,使用3个水龙头接水,接水量分别是(4 4 1 2 1),不考虑插队的话, 第3个人接完水后,第4人接替他的位置继续接水,当第4人接完水后,第1,2人还没有完成接水 ,所以第5人还是接替第4人, 继续接水,此时5人都接完水,花费的总时间是4s. 2、根据上面的描述。我们使用模拟算法,用代码来描述这个接水的过程 3、在模拟的过程中,发现替换接水时,需要找到接水量最少的哪个人所在的水龙头,使用升序排序 4、记录这个模拟过程中,花费的时间,然后输出。

参考代码

#include <bits/stdc++.h>
using namespace std;
int s[11000],ans;    //根据t的终止条件来设置s的大小
int main()
{
    int n,m;cin>>n>>m;
     //输入每个学生的接水量
    for(int i=1;i<=n;i++) cin>>s[i];   
    int t=m+1;   //t用来记录下个学生的编号 
    while(t<=n+m)
    {
        for(int i=1;i<=m;i++) //枚举m个水龙头 
        {
            s[i]--;
            if(s[i]==0)
            {
                s[i]=s[t];     //如果这个学生的水接完了 模拟换下一个学生来这个水龙头
                t++; 
            }
        }
        ans++;      //以上是模拟的1秒钟的接水时间 所有ans加 1
    }
    cout<<ans;
    return 0;
} 

参考2

#include <bits/stdc++.h>
using namespace std;
int s[10005],a;    
int main(){
	int n,m;  
    cin>>n>>m;
    //循环录入n个同学的接水量 
    for(int i=1;i<=n;i++){
    	cin>>a;
    	s[1]+=a;
    	sort(s+1,s+1+m);
	}
    cout<<s[m];
	return 0;
} 

参考3,李云鹏同学的题解,思路非常清晰,适合大家学习

#include<bits/stdc++.h> 
using namespace std;
int n,m,t; //定义n个人,m个水龙头,时间 
int w[10005]; //存储每个人的接水量 
int nt,sum; //下一个接水的人的编号,总接水量 
int main()
{
    cin>>n>>m;
    nt=m+1;  //有m个水龙头,就有m个人接水,下一个一定是m+1号 
    for(int i=1;i<=n;i++)
    {
        cin>>w[i];
        sum+=w[i];  //先把所有人的接水量都加起来    
    } 
    //按接水量模拟
    while(sum!=0) //当还没有接完水的时候继续循环 
    {
        for(int i=1; i<=m; i++) //枚举m个水龙头
        {
            if(w[i]>0)  //在这个水龙头的人的水没接完 
            {
                w[i]--;  //接水量减1 
                sum--;   //总量减1 
            }
            if(w[i]==0)  //在这个水龙头的人接水完了,下个人跟上
            {
                w[i]=w[nt];  //下一个人接替上 
                w[nt]=0;   //重置为0 
                if(nt!=n) nt++;   // 不到最后一个人就更新下一个人的编号 
                /*
                上面两行代码要一块分析,假如最后三个水龙头的水量分别是 5,4,3
                当三秒过后,3号水龙头接完,此时出现w[i]=0, 此时已经没有人可以替换了,
                因为人都用完了,next值不会加1,那么w[i]还是保留最后一个人的接水量,
                然后就死循环了,所以这个地方首先就是将 w[next]清空,防止出现死循环的
                现象。 
                */
            }     
        } 
        t++;  //累计时间 
    }
    cout<<t;
    return 0;
}