一本通1233 接水问题

【题目描述】

学校里有一个水房,水房里一共装有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

【提示】

样例输入#2:

8 4

23 71 87 32 70 93 80 76

样例输出#2:

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秒。

 

思路:一开始我看到这个题感觉就是一道大水题,但是后来我才发现这个题的顺序是不能改变的,必须按顺序接水,我也不知道这样跟贪心有什么关系,应该是一道模拟题才对。一个个接水就要保证一个人接完水才能换下一个人接,而且要按顺序接,那么交换即可。弄一个指针,一直指着下一个要接水的人,等一个人接完水交换就行了。那么循环结束的条件是什么?我想了好久。其实很简单,所有人接完水,当然就结束了,但是按照我这个思路写代码其实不好验证什么时候结束,所以我想,最后一波接水,一定是除了正在接水的人都接完水了,那么我只需要让时间最长的那个人接完,所有人也就都接完了,那么我让答案加上他所需要的时间就行了,然后我这清奇的思路居然A了。

 

代码:

 

#include<iostream>
#include<cstdio>
#include<math.h>
#include<algorithm>
#include<cstring>
using namespace std;
int n,m,ans,sum,t;
int minn=0x4f;
int w[10010],a[10010];
int cmp(int x,int y)
{
 return x>y;
}
int main()
{
    scanf("%d%d",&n,&m);
    int l=m;//这是那个指针,指向下一个要接水的人
    for(int i=1;i<=n;i++)
        scanf("%d",&w[i]);
    while(1){//这里我while(1)是因为我也不知道什么时候会停下来,所以在找到结束条件的时候我输出答案再加一个return  0即可
    minn=0x4f;//每次循环都要初始化为最大值
    for(int i=1;i<=m;i++)
    {
     minn=min(minn,w[i]);
     if(minn==0)//这里注意了,就是结束条件,如果当中的最小值为0,也就是除了这m个人(其实是m-1个人,有一个0)所有人都已经接完水了,那么加上其中最慢的那个人所需要的时间也就是最大值,输出答案即可
     {
      sort(w+1,w+m+1,cmp);//我用的排序找最大值
   ans+=w[1];//w[1]就是最大值
   cout<<ans;//输出之后return  0,不然while(1)死循环
   return 0;
  }
 }
    for(int i=1;i<=m;i++)//如果没有到最后一波,那么找到其中的最小值,先抬走最快的那个人,让下一个人接水,也就是指针指着的人
    {
     w[i]-=minn;//所有人都要减去这个最小值,因为大家是一起接水的
     if(w[i]==0)//找到那个被抬走的人
     {
      swap(w[i],w[l+1]);//跟下一个人换位置
      l++;//指针++
  }
 }
 ans+=minn;//接水当然要花时间,所以加上
}
 return 0;
}//没了
 
 我到底是归类到模拟还是贪心呢。。。。
posted @ 2020-05-13 14:59  徐明拯  阅读(811)  评论(0编辑  收藏  举报