Skip to content

Latest commit

 

History

History
99 lines (64 loc) · 3.96 KB

1993.md

File metadata and controls

99 lines (64 loc) · 3.96 KB

1993题目描述:Hello World for U

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: 给定一个任意字符串,长度在5到80之间,要求按照字符串原来的顺序,呈U字型输出 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. 左边n1,底边n2,右边n3,,满足条件,n1 + n2 + n3 = N, n1 = n3 <= n2; 3 <= n2 <= 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.

  • 样例输入

helloworld!

  • 样例输出

h   !

e  d

l   l

lowor

提示

这一题需要解决的问题是将一个字符串写成U字形。拿到这一题的第一映像是U字的写法(可没有茴香豆的“茴”写法多),先是写第一排第一个字符,然后写第二排第一个字符……然后是最后一排,然后是倒数第二排……但在C语言中如果我们要这样写U字形的字符串就需要在数组中操作了。如果是直接输出的话,那只能自上至下一行一行输出。首先是第一行,写出第一个字符和最后一个字符,第二行写出第二个字符和倒数第二个字符……最后是最后一行。需要注意的是除了最后一行输出所有字符,前面每一行只输出两个字符。中间还有空格来隔开每行的两个字符(具体有多少空格,待会计算)。

思路有了,看看具体的要求。字符串的长度是N,n1,n3代表两边每列字符的数目。n2代表最后一行的字符数。题目中给了一个算式:

n1 = n3 = max { k| k <= n2 for all 3 <= n2 <= N } with n1 + n2 + n3 - 2 = N.

仔细研究这个算式,这里的k是不大于n2的,也就是说n1和n3是不大于n2且满足n1+n2+n3=N+2的最大值。那么自然有n1=n3=(N+2)/3,n2=N+2-(n1+n3)。也就是说设side为两边的字符数(包括最后一行的两端),则side=n1=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 <iostream>
#include <cstring>
using namespace std;
int main() {
    int n1 = 0, n2 = 0;
    char str[81] ={};
    while(cin>>str) {
        int N = strlen(str) + 2;
        //寻找n2的长度
        for (int i = 3; i <= N; i++) {
            if ((N - i) % 2 == 0 && (N - i) / 2 <= i) {
                n2 = i;
                break;
            }
        }
        n1 = (N - n2)/2;
        int L = strlen(str);
        for (int i = 0; i < n1; i++){
            for (int j = 0; j < n2; j++) {
              //输出n1-1行图形
                if (i<n1-1) {
                    if(!j) cout<<str[i];
                    else if(j == n2-1) cout<<str[L-i-1];
                    else cout<<' ';
                }
                else cout<<str[i+j]; //最后一行,刚好是中间的n2个元素,所以i+j;
            }cout<<endl;
        }
    }
    return 0;
}

二位数组cout<<\v[i]; 如果行间有空字符,只显示第一个非空字符.