Gym - 101670B(Pond Cascade )二分或贪心

版权声明:SDKD-Vici__ https://blog.csdn.net/Vici__/article/details/83244899

题意:

给定n个池塘,往里面注水,给定单位时间的注水量。

注:1、这n个池塘是同时注水的,也就是说任一时间内,每个池塘注入的水量是相同的。

2、这n个池塘所在高度是逐渐递减的,如果第i个池塘满了后继续注水,水将会往第i+1个池塘流,依次类推。

求①最后一个池塘刚好满的时间;②所有池塘刚好满的时间。

题解:

一、二分时间,检验答案

二、直接贪心

一、二分时间,检验答案(详解见代码)

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const double INF=1e9+10;
ll a[maxn];
ll n,f;
bool judge1(double t)
{
    double sum=0;//记录所有池塘的溢出量
    for(int i=0;i<n-1;i++)
    {
        sum+=t*f;//每次往里面注入 t*f 单位的水
        if(sum<a[i])//和第i池塘的容量作比较
            sum=0;//如果小于a[i] 则sum里的水全部进入第i个池塘里面
        else
            sum-=a[i];//否则sum里的水变为 sum-a[i]
    }
    sum+=t*f;
    if(sum>=a[n-1])//循环结束后 如果sum里的水大于等于最后一个的容量,则说明t时间内最后一个池塘会注满
        return true;
    else
        return false;
}
bool judge2(double t)
{
    double sum=0;//记录所有池塘的溢出量
    for(int i=0;i<n;i++)
    {
        sum+=t*f;//每次往里面注入 t*f 单位的水
        if(sum<a[i])//和第i池塘的容量作比较,如果sum里的水小于第i个池塘的容量,则说明有池塘不满,直接返回false
            return false;
        sum-=a[i];//否则sum里的水变为 sum-a[i]
    }
    return true;
}
int main()
{
    int K=100;//(100次二分,精确答案)
    while(scanf("%lld%lld",&n,&f)!=EOF)
    {
        ll MAX=0;
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++)
        {
            scanf("%lld",&a[i]);
        }
// 1.
        double l=0,r=INF;
        double t1,t2;
        K=100;
        while(K--)
        {
            double mid=(l+r)/2;
            if(judge1(mid))
            {
                r=mid;
            }
            else
            {
                l=mid;
            }
        } t1=r;
// 2.
        K=100;
        l=0,r=INF;
        while(K--)
        {
            double mid=(l+r)/2;
            if(judge2(mid))
            {
                r=mid;
            }
            else
            {
                l=mid;
            }
        } t2=r;
        printf("%.6lf %.6lf\n",t1,t2);
    }
    return 0;
}

二、直接贪心

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const double INF=1e9+10;
ll a[maxn];
int main()
{
    ll n,f;
    while(scanf("%lld%lld",&n,&f)!=EOF)
    {
        memset(a,0,sizeof(a));
        for(int i=0;i<n;i++)
        {
            scanf("%lld",&a[i]);
        }
// 1.
        double su1=0,sum1=0,t1=INF;
        for(int i=n-1;i>=0;i--) //从最后一个池塘开始
        {
            sum1+=a[i];
            su1+=f;
            t1=min(t1,sum1*1.0/su1);//求最后m个所有时间的平均值
        }
// 2.
        double su2=0,sum2=0,t2=0;
        for(int i=0;i<n;i++)
        {
            sum2+=a[i];
            su2+=f;
            t2=max(t2,sum2*1.0/su2);
        }
        printf("%.6lf %.6lf\n",t1,t2);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Vici__/article/details/83244899
今日推荐