题目描述:
Given any string of N ( ≥ \ge ≥ 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 n 1 n_1 n1 characters, then left to right along the bottom line with n 2 n_2 n2 characters, and finally bottom-up along the vertical line with n 3 n_3 n3 characters. And more, we would like U to be as squared as possible —— that is, it must be satisfied that n 1 n_1 n1 = n 3 n_3 n3 = max { k| k ≤ \le ≤ n 2 n_2 n2 for all 3 ≤ \le ≤ n 2 n_2 n2 ≤ \le ≤ N } with n 1 n_1 n1 + n 2 n_2 n2 + n 3 n_3 n3 - 2 = N.
输入:
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.
输出:
For each test case, print the input string in the shape of U as specified in the description.
样例输入:
helloworld!
样例输出:
h !
e d
l l
lowor
提示:
这一题需要解决的问题是将一个字符串写成U字形。拿到这一题的第一映像是U字的写法(可没有茴香豆的“茴”写法多),先是写第一排第一个字符,然后写第二排第一个字符……然后是最后一排,然后是倒数第二排……但在C语言中如果我们要这样写U字形的字符串就需要在数组中操作了。如果是直接输出的话,那只能自上至下一行一行输出。首先是第一行,写出第一个字符和最后一个字符,第二行写出第二个字符和倒数第二个字符……最后是最后一行。需要注意的是除了最后一行输出所有字符,前面每一行只输出两个字符。中间还有空格来隔开每行的两个字符(具体有多少空格,待会计算)。
思路有了,看看具体的要求。字符串的长度是N, n 1 n_1 n1, n 3 n_3 n3代表两边每列字符的数目。 n 2 n_2 n2代表最后一行的字符数。题目中给了一个算式:
n 1 n_1 n1 = n 3 n_3 n3 = max { k| k ≤ \le ≤ n 2 n_2 n2 for all 3 ≤ \le ≤ n 2 n_2 n2 ≤ \le ≤ N } with n 1 n_1 n1 + n 2 n_2 n2 + n 3 n_3 n3 - 2 = N.
仔细研究这个算式,这里的k是不大于 n 2 n_2 n2的,也就是说 n 1 n_1 n1和 n 3 n_3 n3是不大于 n 2 n_2 n2且满足 n 1 n_1 n1+ n 2 n_2 n2+ n 3 n_3 n3=N+2的最大值。那么自然有 n 1 n_1 n1= n 3 n_3 n3=(N+2)/3, n 2 n_2 n2=N+2-( n 1 n_1 n1+ n 3 n_3 n3)。也就是说设side为两边的字符数(包括最后一行的两端),则side= n 1 n_1 n1= n 3 n_3 n3=(N+2)/3。设mid为最后一行除去两端的两个字符后剩下的字符数,mid=N-side*2(总长度减去两边的字符数)。同时mid也是我们输出除最后一行外前面所有行需要空出的空格数。
最后如何在第一行输出第一个字符和最后一个字符呢?那自然是str[0]和str[len-1-i](len为字符串的长度,也就是N)。
于是问题完美解决,步骤如下:
1)计算字符串长度len;
2)计算两边的字符数side=(len+2)/3;
3)计算最后一行中间的字符数(前面每行中间的空格数);
4)输出每行相应的字符。
由于该题目不难,也没有什么需要特别注意的,我也就不写注意点了。具体细节详见参考代码。
实现代码:
#include<cstdio>
#include<string>
#include<iostream>
using namespace std;
int main() {
string str;
while(cin >> str) {
int length = str.size();
int n1, n3;
n1 = n3 = (length + 2) / 3;
int n2 = length - n1 * 2 + 2;
int spaceNum = n2 - 2;
for(int i = 0; i < n1 - 1; i++) {
printf("%c", str[i]);
for(int j = 0; j < spaceNum; j++) {
printf(" ");
}
printf("%c", str[length - 1 - i]);
printf("\n");
}
cout << str.substr(n1 - 1, n2) << endl;
}
return 0;
}