题解分析
分析问题: 本题使用贪心+模拟,难度是普及组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;
}