题意:给出数 k 和一个字符串,字符串中包含空格和连号 '-' ,我们可以在空格或连号处断开一行,最多可以有 k 行,问可能的最小宽度。如:
4
garage for sa-le
最多可有 4 行,最小宽度为 7 , 即:(空格用 '.' 表示)
garage.
for.
sa-
le
tags:二分最小宽度即可。 每次 check 尽可能少断开,看行数是否 <= k 。
// 803D #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define rep(i,a,b) for (int i=a; i<=b; ++i) #define per(i,b,a) for (int i=b; i>=a; --i) #define mes(a,b) memset(a,b,sizeof(a)) #define INF 0x3f3f3f3f #define MP make_pair #define PB push_back #define fi first #define se second typedef long long ll; const int N = 2000005; int k, len, p[N], cnt; char str[N]; bool check(int x) { int pos=0, ans=0; for(int i=1; i<=cnt; ++i) { if(p[i+1]-pos+1 > x) { if(p[i]-pos+1 > x) return false; pos=p[i]+1, ++ans; } } if(ans>k) return false; return true; } int main() { scanf("%d", &k); getchar(); gets(str); len = strlen(str); rep(i,0,len-1) if(str[i]==' ' || str[i]=='-') p[++cnt]=i; p[++cnt]=len-1, p[++cnt]=INF; int l=1, r=len, ans, mid; while(l<=r) { mid = l+r>>1; if(check(mid)) ans=mid, r=mid-1; else l=mid+1; } printf("%d ", ans); return 0; }