C - Present
Description
Little beaver is a beginner programmer, so informatics is his favorite subject. Soon his informatics teacher is going to have a birthday and the beaver has decided to prepare a present for her. He planted n flowers in a row on his windowsill and started waiting for them to grow. However, after some time the beaver noticed that the flowers stopped growing. The beaver thinks it is bad manners to present little flowers. So he decided to come up with some solutions.
There are m days left to the birthday. The height of the i-th flower (assume that the flowers in the row are numbered from 1 to n from left to right) is equal to ai at the moment. At each of the remaining m days the beaver can take a special watering and water wcontiguous flowers (he can do that only once at a day). At that each watered flower grows by one height unit on that day. The beaver wants the height of the smallest flower be as large as possible in the end. What maximum height of the smallest flower can he get?
Input
The first line contains space-separated integers n, m and w(1 ≤ w ≤ n ≤ 105; 1 ≤ m ≤ 105). The second line contains space-separated integers a1, a2, ..., an(1 ≤ ai ≤ 109).
Output
Print a single integer — the maximum final height of the smallest flower.
Sample Input
Input6 2 3
2 2 2 2 1 1Output2Input2 5 1
5 8Output9
先说题意:共有n盆花列为一排,输入n盆花的现高度,可浇水m天,每天只能浇一次,每次浇水只能浇相邻的w株,每浇水一次花长高1,求m天后最矮的花最高为多少。
可用二分答案的方法,将可能的高度二分,再比较在m天内能不能达到二分的数值,若能则继续向上二分答案,若不能则向下二分答案,直到找出最合适的值。
附AC代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 8 const int MAX=101000; 9 long long a[MAX],b[MAX],v[MAX]; 10 11 int main(){ 12 int n,m,w; 13 while(~scanf("%d %d %d",&n,&m,&w)){ 14 long long low=1e9,top=-1; 15 for(int i=1;i<=n;i++){ 16 scanf("%I64d",&a[i]); 17 if(a[i]<low) 18 low=a[i]; 19 if(a[i]>top) 20 top=a[i]; 21 } 22 top+=m; 23 long long mid,ans=-1; 24 while(top>=low){ 25 mid=(top+low)/2;//中点 26 for(int i=1;i<=n;i++) 27 b[i]=max(mid-a[i],(long long)0);//到达中点所需要的天数 28 memset(v,0,sizeof(v));//v数组用来实现连续浇水w 29 long long day=m;//day表示天数 30 long long c=0;//已浇水天数 31 for(int i=1;i<=n;i++){ 32 c+=v[i];//w个后c归零 33 b[i]-=c;//已浇c天 34 if(b[i]>0){ 35 day-=b[i]; 36 if(day<0)//天数不够 37 break; 38 else 39 c+=b[i]; 40 v[i+w]-=b[i];//当i循环到w个后时,这些花之前并没有被浇水,所以减去,由循环开头式子得c=0 41 b[i]=0;//已交够水了所以为0 42 } 43 } 44 if(day<0){//当天数不够时向下二分答案 45 top=mid-1; 46 } 47 else{//继续向上二分 48 ans=mid; 49 low=mid+1; 50 } 51 } 52 printf("%I64d\n",ans); 53 } 54 return 0; 55 }