PAT-A 1031. Hello World for U (20)

题目链接在此

题意理解

将给定的字符串按照U形进行输出。其中n1为左侧竖线包含的字符数,n2位底部包含的字符数,n3位右侧竖线包含的字符数,n1,n2,n3都包含拐角处的字符,于是有n1+n2+n3-2=N。此外,n1,n2,n3还需要满足以下条件:
1. n1==n3
2. n2 >= n1
3. 在满足以上条件的前提下,n1尽可能大

思路

对于“图形输出”的题型,一般都是两种方法:
1. 找到规律,直接输出
2. 找到规律,填入数组,输出数组

对于这个题,我第一次想到的是填数组的方法,详细介绍一下这个方法,至于直接输出的方法,只需要注意输出字符和空格的时机即可。

通过“题意理解”,我们可以列出几个式子:
n1<=n2
n3<=n2
n1+n2+n3-2 = N
这样一来,我们可以得到n2>=(N+3)/2,那么,当n1=n3=(N+3)/2
时是符合题意的,故n2=N-n1-n3+2。(具体过程读者自行演算、理解)

接下来就是将U分成左-下-右三个部分,填入print数组,细节不表,看代码即可。

这里需要注意:print数组需要初始化为全空格、print数组的大小如果是固定大小,至少需要[28][28](根据式子且N<80可推出)。

填入数组法代码

#include<stdio.h>
#include<string.h>

int main(){

    char str[81];
    int index = 0;

    scanf("%s",str);

    int n = strlen(str);

    int n1,n2,n3;

    n1 = n3 = (n+2)/3;
    n2 = n-n1-n3+2;

    char print[n1][n2];

    //初始化print数组
    for(int i = 0 ;i < n1; i++){
        for(int j = 0; j < n2; j++){
            print[i][j] = ' ';
        }
    } 

    //填充n1 
    for(int i = 0; i < n1; i++){
        print[i][0] = str[index++];
    }   
    index--;

    //填充n2
    for(int i = 0; i < n2; i++){
        print[n1-1][i] = str[index++]; 
    } 
    index--;

    //填充n3
    for(int i = n3-1 ; i >= 0; i--){
        print[i][n2-1] = str[index++];
    } 

    //输出print数组
    for(int i = 0 ; i < n1; i++){
        for(int j = 0; j < n2; j++){
            printf("%c",print[i][j]);
        }
        printf("\n");
    } 

    return 0;
}

直接输出法代码

不详细介绍,仍然需要通过上面的三个式子计算出n1,n2,n3的值,通过它们的值控制输出的行和列,以及每行的输出情况。

我的代码是用了left和right两个“指针”来控制输入字符串str[]数组的元素获取,也可以像《算法笔记》上通过N和循环变量的关系来得到需要输出的元素,皆可。

#include<stdio.h>
#include<string.h>

int main(){

    char str[81];
    scanf("%s",str);

    int n1,n2,n3,n;

    n = strlen(str);    
    n1 = n3 = (n+2)/3;
    n2 = n-n1-n3+2;

    int left = 0, right = n-1;

    for(int i = 0 ; i < n1; i++){
        for(int j = 0; j < n2; j++){
            if( i < n1-1 ){ //输出n1和n3 
                if(j == 0){
                    printf("%c",str[left++]);
                } else if( j == n2-1){
                    printf("%c",str[right--]);
                }else{
                    printf(" "); 
                } 
            }else{
                printf("%c",str[left++]);
            }
        }
        printf("\n");
    }

    return 0;
}

我把输出控制(是输出符号还是输出空格)放到了循环变量里,也可以在每一行中,直接先输出左侧,然后输出中间,再输出右边,这样就不需要两个循环变量之间的关系了。(《算法笔记》是这种方式)

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值