题目
Given any string of N (≥5) characters, you are asked to form the characters into the shape of U. For example, helloworld can be printed as:
h d
e l
l r
lowo
That is, the characters must be printed in the original order, starting top-down from the left vertical line with n1 characters, then left to right along the bottom line with n2 characters, and finally bottom-up along the vertical line with n3 characters. And more, we would like U to be as squared as possible -- that is, it must be satisfied that n1 =n3 =max { k | k≤n2 for all 3≤n2 ≤N } with n1 +n2 +n3 −2=N.
Input Specification:
Each input file contains one test case. Each case contains one string with no less than 5 and no more than 80 characters in a line. The string contains no white space.
Output Specification:
For each test case, print the input string in the shape of U as specified in the description.
Sample Input:
helloworld!
Sample Output:
h !
e d
l l
lowor
题目解读
- 给定一个长度在
5-80
之间、不包含空格的字符串,将它转变成U
型 输出。 n1
和n3
是左右两条竖线从上到下的字符个数,n2
是底部横线从左到右的字符个数。n1 = n3 = max { k | k ≤ n2 for all 3 ≤ n2 ≤ N } ; n1 + n2 + n3 - 2 = N
思路分析
这个题最关键的地方就是确定 U
的两竖有多高,一横有多宽,也就是确定n1,n2,n3
。
我们可以根据题目中的关系式n1 = n3 = max { k | k≤n2 for all 3≤n2 ≤N }
得到n1<=n2
,进一步推导得到 N + 2 = n1 + n2 + n3 >= n1 + n1 + n3 = 3 * n1 ==> n1 <= (N + 2) / 3
所以 n1 = (N + 2) / 3,n3 = n1,n2 = N - n1 - n3 = N - 2 * n1
;
接下来就是输出,可以初始化一个二维字符数组,刚开始填上空白,然后把U对应的位置填上,最后输出。
我这里采用的是直接按行输出。
比如题目给出的helloworld!
,为了方便发现规律,我把索引标出来
0 h ! 10
1 e d 9
2 l l 8
3 lowor 7
456
发现,最后一行(U的那一横)上面的行(n1 - 1行),都是两个字符,每一行第一个字符就是原串按顺序输出的字符,然后中间有n2-2
个空格,下一个字符在原串哪个位置呢??原串长度是11,0+10 = 10,1 + 9 = 10, 2+8 = 10
, 看出来么???两个字符在原串中的索引加起来等于原串的长度-1。
n1-1
行第一个字符输出到原串第n1-2
个位置上,至于最后一个横行,就接着这个位置输出原串,一共有n2
个字符就可以了。(看索引就明白了)
完整代码
#include <iostream>
#include <string.h>
using namespace std;
/**
* 题目大意:用所给字符串按U型输出。n1和n3是左右两条竖线从上到下的字符个数,n2是底部横线从左到右的字符个数。
* 要求:n1 == n3; n1 >= n2; n1 + n2 + n3 - 2 = N
* N + 2 = n1 + n2 + n3 >= n1 + n1 + n3 = 3 * n1 ==> n1 <= (N + 2) / 3
* 题目要求让 U 尽可能 "squared" 所以n1要尽可能大。因此n1取值 (N + 2) / 3
*/
int main() {
char str[80];
cin >> str;
int len = strlen(str);
int n1 = (len + 2) / 3, n2 = len - 2 * n1 +2;
// 输出到原串哪个字符了
int i = 0;
// U的两竖线,最后一行之上的行(U的那一横之上),共n1-1行,
for (; i < n1 - 1; ++i) {
// 每一行第一个字符
cout << str[i];
// 中间有 n2 - 2个空格
for (int j = 1; j < n2 - 1; ++j)
cout << " ";
// 每一行最后一个字符,这两字符在原串中的位置满足 x + y = len - 1
cout << str[len - i - 1] << endl;
}
// 输出最后一行 n2个字符
while(n2-- > 0)
cout << str[i++];
return 0;
}