题目:
Description
当开始学习程序语言,第一个程序肯定是在屏幕上输出一些字符,比如输出”Hello World!”。
遇到输出的句子过长时,输出的句子由于换行将被屏幕截断。现在给你一些文本,文本的文法如下:
TEXT(文本):= SENTENCE | SENTENCE SPACE TEXT
SENTENCE(句子):= WORD SPACE SENTENCE | WORD END
END(结束符):= {‘.’, ‘?’, ‘!’}
WORD(单词):= LETTER | LETTER WORD
LETTER(字母):= {‘a’..’z’, ‘A’..’Z’}
SPACE(空格):= ’ ’
你的任务是把满足上述文法的文本分割成多行(每行文本的长度都不超过n)。并且满足如下条件:
一、 输出的句子不能被截断。如:”Hi! Welcome to ECNU.”若被分割成”Hi! Welcome”则认为被截断,即不合法。
二、 文本分割后保证行数最小。如:”Hi! Welcome to ECNU. Have a nice day!”在每行文本长度要求在n=20的情况下,可以分割为:”Hi!”“Welcome to ECNU.”“Have a nice day!”,也可以被分割为:”Hi! Welcome to ECNU.””Have a nice day!”此时认为第二种分法才合法。
注意:如果两个相邻的句子被分割到两行,句子中间的空格可以被忽略。
Input
第1行为测试数据组数T(T <= 100),接下来为T组数据。
每组数据包含2行,第1行为屏幕每行最多可以显示的字符数n(2 <= n <= 255)。第二行为文本,字符总数不超过10001,并且保证符合上述文法。
Output
输出包含T行,每行输出分解后的文本最少需要的屏幕行数。如果无法达到要求,则输出”Impossible”(不要输出引号)。
Sample Input
3
12
Hello World!
11
HelloWorld!
40
Hello. Welcome to East China Normal University! Whatis your name?
Sample Output
1
Impossible
3
代码
#include<stdio.h>
#include<string.h>
char str[10010];
int num[5010];//每个句子的个数
int main()
{
int T;
int n;
int i;
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);//每行的限制字符个数
getchar();//丢弃上一个换行
gets(str);//输入文本
int l=strlen(str);//文本的长度
int cn=0;//统计句子的长度
int k=0;//句子长度数组的下标
i=0; // 遍历字符串的变量
while(i<l) //从0开始遍历
{
if(str[i]=='.'||str[i]=='?'||str[i]=='!')//遇到句子结束为止
{
cn++;
i+=2;//跳过空格,没有这一步的话,cn会多记,见第32行
num[k]=cn;
k++;
cn=0;//长度清空
}
else
{
cn++;
i++;
}
}
int flag=1;
for(i=0; i<k; i++)
{
if(num[i]>n)//单个句子字符数大于限制的个数
{
flag=0;
break;
}
}
if(flag==0)
printf("Impossible\n");
else
{
int h=1;//行数为1
int sum=0;//累计的字符数
for(i=0; i<k; i++)
{
if(sum+num[i]<=n)
{
sum+=num[i];
}
else //累加句子字符数大于限制个数
{
h++;
sum=num[i];//清空
}
}
printf("%d\n",h);
}
}
return 0;
}