Gym - 101670B(Pond Cascade )二分或貪心
阿新 • • 發佈:2018-10-31
題意:
給定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; }