PAT/算法笔记 1031 Hello World for U (20分)

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 n​1​​ characters, then left to right along the bottom line with n​2​​ characters, and finally bottom-up along the vertical line with n​3​​ characters. And more, we would like U to be as squared as possible -- that is, it must be satisfied that n​1​​=n​3​​=max { k | k≤n​2​​ for all 3≤n​2​​≤N } with n​1​​+n​2​​+n​3​​−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

Codeup平台自带解析:

这一题需要解决的问题是将一个字符串写成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)输出每行相应的字符。

代码1:注意PAT平台不支持gets方式,所以用scanf方法接收字符串

//此方法使用二维数组方式进行输出
#include <cstring>//必须是cstring,否则strlen()方法不能用
#include <stdio.h>
int main(){
    char str[100];
    char ans[40][40];
    int n1,n2,n3;
    scanf("%s",str);
    int n=strlen(str);//获取输入的字符串的长度长度
    n1=(n+2)/3,n3=n1,n2=n+2-n1-n3;//公式
    for(int i=1;i<=n1;i++){
        for(int j=1;j<=n2;j++){
            ans[i][j]=' ';//初始化,将二维数组全部赋为空格
        }
    }
    int p=0;//从0开始使用str数组
    for(int i=1;i<=n1;i++){
        ans[i][1]=str[p++];//输入最左边第一列,从上往下赋值n1个字符
    }
    for(int j=2;j<=n2;j++){
        ans[n1][j]=str[p++];//输入最底下一行,从左往右赋值n2个字符
        }
    for(int k=n3-1;k>=1;k--){
        ans[k][n2]=str[p++];//输入最右边一列,从下往上赋值n3个字符
    }
    for(int i=1;i<=n1;i++){
        for(int j=1;j<=n2;j++){
            printf("%c",ans[i][j]);//打印数组
        }
        printf("\n");
    }
    return 0;
    }

代码2 

//不用二维数组,直接输出方式
#include<cstdio>
#include<cstring>
int main(){
    int n,n1,n2,n3;
    char str[100];
    gets(str);
    n=strlen(str);
    n1=(n+2)/3,n3=n1,n2=n+2-n1-n3;//公式
    for(int i=0;i<n1-1;i++){//输出前n-1行
        printf("%c",str[i]);
        for(int j=0;j<n2-2;j++){//输出n-2个空格
            printf(" ");
        }
        printf("%c\n",str[n-i-1]);//输出当前行的右侧字符,数组倒着输出
    }
    for(int i=0;i<n2;i++){
        printf("%c",str[n1+i-1]);//输出底部的n2个字符
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值