传送门:http://codeforces.com/problemset/problem/803/D
题意:输入一个k和一个字符串s,最多可以把s分成k行,分割位置只能是-或者空格,求分割后最长一行长度的最小值。
思路:二分答案。用st存放两个可分割点间差距最大的距离(首尾别忘了处理),把[st,s.size()]作为初始二分区间,如果mid切出来的行数大于题目给出的行数k,那么说明每行放的太少了,所以行数会超出,所以需要让左边界等于mid+1.反之也是这样思考。
代码:
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<string>
#include<iostream>
#include<map>
#include<vector>
#include<set>
#include<queue>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxv=1e6+6;
string s;
int k,co,a[maxv],st;
int cnt(int x)
{
int c=1,sum=0;
for(int i=0;i<co;i++)
{
sum+=a[i];
if(sum>x)
{
c++;
sum=a[i];
}
}
return c;
}
int main()
{
cin>>k;
getchar();
getline(cin,s);
int pos=-1;
int ll=s.size(),i;
for(i=0;i<ll;i++)
{
if(s[i]=='-'||s[i]==' ')
{
st=max(st,i-pos);
a[co++]=i-pos;
pos=i;
}
}
a[co++]=i-pos-1;
st=max(st,i-pos-1);
int l=st,r=ll;
while(l<=r)
{
int mid=(l+r)/2;
if(cnt(mid)<=k)
r=mid-1;
else
l=mid+1;
}
printf("%d\n",l);
return 0;
}