codevs 1415 比那名居天子
题目描述 Description
在幻想乡, 比那名居天子是管理着『要石』的人。能够引发和镇压地震存当然也可以用来改变地形。因为在幻想乡引发地震,而被灵梦等人教训了之后天子不得使用『要石』来修复地面。幻想乡可以视为长度为N个格子的一条横轴,其中有些格子的土地由于震被破坏 (记为1) ,有些格子则没(记为0) 。每次使用『要石』,可以把一段长度为L的格子全部修复完成 (即将 1变为 0,L覆盖的范围可以超出地图 ),当然L越大,使用时所花费的灵力也就越多。天子希望最多使用 K次『要石』就将所有被破坏的土地全部修复完成 (即将 1全部变为 0) ,并且花费尽可能小的灵力。她想知道够达到这个目,并且花费尽可能小的灵力。她想知道够达到这个目L最小是多少。
输入描述 Input Description
第 1行: 2个整数,N, K
第 2行: 1个 01 串,长度为 N
输出描述 Output Description
第1行:1个整数,L的最小值
样例输入 Sample Input
10 3
0101111011
样例输出 Sample Output
3
数据范围及提示 Data Size & Hint
样例解释
0101111011>0000111011>00000000011>0000000000
数据范围
对于60% 的数据:1 ≤ N,K 5,000
对于 100% 的数据:1 ≤ N,K 500,000
思路:
二分长度,每次代入原串检验,如果条数小于或等于k,则答案可行。
代码:
#include<cstdio> #include<cstring> using namespace std; char s[500001]; int n,k,ans; bool pd(int x) { int i=0,sum=0; while(i<n) { if(s[i]=='1') i+=x,sum++; else i++; if(sum>k) return 0; } return 1; } int main() { int i,j; scanf("%d%d",&n,&k); scanf("%s",s); int l=0,r=n-1; while(l<=r) { int mid=(l+r)>>1; if(pd(mid)) ans=mid,r=mid-1; else l=mid+1; } printf("%d",ans); return 0; }