您的位置:首页 > 其它

CF Educational Codeforces Round 20 D. Magazine Ad

2017-05-11 09:16 330 查看
原题:

D. Magazine Ad

time limit per test

1 second

memory limit per test

256 megabytes

input

standard input

output

standard output

The main city magazine offers its readers an opportunity to publish their ads. The format of the ad should be like this:

There are space-separated non-empty words of lowercase and uppercase Latin letters.

There are hyphen characters ‘-’ in some words, their positions set word wrapping points. Word can include more than one hyphen.

It is guaranteed that there are no adjacent spaces and no adjacent hyphens. No hyphen is adjacent to space. There are no spaces and no hyphens before the first word and after the last word.

When the word is wrapped, the part of the word before hyphen and the hyphen itself stay on current line and the next part of the word is put on the next line. You can also put line break between two words, in that case the space stays on current line. Check notes for better understanding.

The ad can occupy no more that k lines and should have minimal width. The width of the ad is the maximal length of string (letters, spaces and hyphens are counted) in it.

You should write a program that will find minimal width of the ad.

Input

The first line contains number k (1 ≤ k ≤ 105).

The second line contains the text of the ad — non-empty space-separated words of lowercase and uppercase Latin letters and hyphens. Total length of the ad don’t exceed 106 characters.

Output

Output minimal width of the ad.

Examples

Input

4

garage for sa-le

Output

7

Input

4

Edu-ca-tion-al Ro-unds are so fun

Output

10

Note

Here all spaces are replaced with dots.

In the first example one of possible results after all word wraps looks like this:

garage.

for.

sa-

le

The second example:

Edu-ca-

tion-al.

Ro-unds.

are.so.fun

中文:

想给你一个整数k,然后给你一个带有空格和’-‘的字符串,如果有空格和’-‘可以进行换行(要求空格和’-‘必须在换到上一行的字符串的结尾)。现在让你最多换k行,问你在满足上面换行条件下,换行后的一列字符串中,最长字符串最短。

//自己写保存中间结果的代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

vector<string> vs;

int main()
{
ios::sync_with_stdio(false);
int n;
string s;
while(cin>>n)
{
cin.ignore();
getline(cin,s);
string tmp;
vs.clear();

for(int i=0;i<s.size();i++)
{
if(s[i]!=' '&&s[i]!='-')
tmp+=s[i];
else
{
tmp+='.';
vs.push_back(tmp);
tmp.clear();
}
}
vs.push_back(tmp);
int L=1,R=s.size(),mid;
int ans,res=0;

while(R-L>1)
{
mid=(L+R)/2;
//        cout<<L<<" "<<mid<<" "<<R<<endl;
//        mid=8;
ans=1;//
res=0;
for(int i=0;i<vs.size();)
{
if(res+vs[i].size()<=mid)
{
res+=vs[i].size();
i++;
}
else
{
if(res==0)
break;
ans++;
res=0;
}
}
//           for(int i=0;i<ans.size();i++)
//               cout<<ans[i]<<endl;
if(res==0)
L=mid;
else
{
if(ans<=n)
R=mid;
else
L=mid;
}
}
cout<<R<<endl;
}
return 0;
}


//别人的代码
#include <iostream>
using namespace std;
const int INF = (int)1e9;
int n,k,r,l;
string s;
int solve(int w)
{
int ans = 0;
int l = 0;
while(l < n)
{
ans++;
int r = l + w;
if (r >= n) break;
while(r > l && s[r - 1] != ' ' && s[r - 1] != '-') r--;
if (r == l) return INF;
l = r;
}
return ans;
}

int main()
{
cin >> k;
getline(cin, s);
getline(cin, s);
n = s.length();
int l = 0, r = n;
while(r - l > 1)
{
int m = (l + r) / 2;
if (solve(m) <= k)//小于等于
r = m;
else
l = m;
}
cout << r << endl;//输出右端点
return 0;
}


思路:

最大值最小,最小值最大等等问题是典型的二分法问题。

此题也不例外

大概思路如下:

二分最长字符串的长度上界mid,然后按照长度mid划分字符串换行。如果换行的个数大于k,那说明二分的长度上界太短了,分出的行数过多,否则分出的行数如果小于等于k,那就说明还可以把字符串拉长一些。按照二分得到的字符串长度上界,贪心累加字符串长度,如此下来,时间复杂度为 二分 * 字符串长度O(M*logN)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: