codeforces #262 DIV2 C称号Present(二分法+贪婪)
职务地址:http://codeforces.com/contest/460/problem/C
这个题是用二分枚举最小值。然后推断是否能在规定的次数内使得全部的数都达到这个值。推断的时候要用贪心的方法推断,从左往右遍历。这时候须要让每次浇花的范围尽量向右。所以当到达一个不得不浇花的地方时,要继续占用所须要的浇花次数。当浇花次数不够用的时候,就说明无法达到。
在我的代码中,c数组是记录当前到了该点的时候浇花范围的最右界。表示到了这个地方的时候少了多少次覆盖。y就代表当前这个数被多少个浇花范围覆盖。x是指还剩余的浇花次数。
忘了初始化。。二分非常明显不好调试。
。调了将近20分钟才发现忘了对C数组初始化。。
。sad。
。。。
代码例如以下:
#include <iostream> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <math.h> #include <ctype.h> #include <algorithm> #include <queue> using namespace std; #define LL __int64 LL a[110000], b[110000], c[110000]; int main() { LL n, m, i, w, ans, x, y; scanf("%I64d%I64d%I64d",&n,&m,&w); for(i=0;i<n;i++) { scanf("%I64d",&a[i]); } memset(c,0,sizeof(c)); LL low=1, high=1e10, mid; while(low<=high) { mid=(high+low)/2; //printf("%I64d\n",mid); x=m; y=0; memset(c,0,sizeof(c)); int flag=0; for(i=0;i<n;i++) { b[i]=mid-a[i]; if(b[i]<0) b[i]=0; } for(i=0;i<n;i++) { y+=c[i]; b[i]-=y; if(b[i]>0) { if(x-b[i]<0) { flag=1; break; } else { x-=b[i]; y+=b[i]; if(i+w<n) c[i+w]-=b[i]; } } } //printf("%I64d %d\n",mid, flag); if(flag) { high=mid-1; } else { ans=mid; low=mid+1; } //printf("%I64d\n",ans); } printf("%I64d\n",ans); return 0; }
版权声明:本文博客原创文章。博客,未经同意,不得转载。