• 接水问题(贪心课后题顺序查找是什么鬼)


    15:接水问题

    总时间限制: 
    1000ms
     
    内存限制: 
    65536kB
    描述

    学校里有一个水房,水房里一共装有 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 ≤ n ≤ 10000,1 ≤ m ≤ 100 且 m ≤ n;
    1 ≤ wi ≤ 100。
    输出
    输出只有一行,1 个整数,表示接水所需的总时间。
    样例输入
    样例 #1:
    5 3
    4 4 1 2 1
    
    样例 #2:
    8 4
    23 71 87 32 70 93 80 76
    样例输出
    样例 #1:
    4
    
    样例 #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 秒。
    来源
    NOIP2010复赛 普及组 第二题
    【神的分析】感觉我思路有点奇葩,可是就是这么推出来的呀,,只是代码实现了而已。
    【代码妹子】
     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstdlib>
     4 #include<algorithm>
     5 using namespace std;
     6 int Time[10009];
     7 int n,m,maxx=0;
     8 int main()
     9 {
    10     scanf("%d%d",&n,&m);
    11     for(int i=1;i<=n;i++)
    12     {
    13         scanf("%d",&Time[i]);
    14         maxx=max(maxx,Time[i]);//接水时间最长的找出来 
    15     }
    16     if(m>=n)
    17     {
    18         printf("%d",maxx);//如果水龙头够分的话时间就是最长时间,输出最长时间结束程序就好了 
    19         return 0;
    20     }
    21     int l=1,r=m,tot=0;//如果水龙头不够就挨个轮呗 
    22     for(int j=l;j<=n-m+1;j++)//m个水龙头从左向右移动,也就是长为m的区间平移 
    23     {
    24         sort(Time+l,Time+r+1);//排序后的第一个就是花费最短时间的 
    25         if(r==n)//建议先看完下面的for循环再看这个if语句 
    26         {
    27             tot+=Time[r];//当右移到头时,最后m个人一定是花费时间一定是m个人中的最长时间 
    28             printf("%d",tot);//所以tot要加入排序后的最后一个 
    29             return 0;//结束 
    30         }
    31         for(int i=l+1;i<=r;i++)//注意这里一定要从l+1开始循环,因为要减去Time[l],不能让它的值先改变改变 
    32         {
    33             Time[i]-=Time[l];//每个人的时间减去Time[l],也就是减去这m个水龙头中最少的时间 
    34         }
    35         tot+=Time[l];//总时间加上这个刚走的人的时间(刚走的人就是排序后最小的呀) 
    36         l++;r++;//区间向右移动,继续下一个人; 
    37     }
    38     return 0;
    39 }
  • 相关阅读:
    【leetcode】1215.Stepping Numbers
    【leetcode】1214.Two Sum BSTs
    【leetcode】1213.Intersection of Three Sorted Arrays
    【leetcode】1210. Minimum Moves to Reach Target with Rotations
    【leetcode】1209. Remove All Adjacent Duplicates in String II
    【leetcode】1208. Get Equal Substrings Within Budget
    【leetcode】1207. Unique Number of Occurrences
    【leetcode】689. Maximum Sum of 3 Non-Overlapping Subarrays
    【leetcode】LCP 3. Programmable Robot
    【leetcode】LCP 1. Guess Numbers
  • 原文地址:https://www.cnblogs.com/zzyh/p/6646923.html
Copyright © 2020-2023  润新知