首页 > 学院 > 开发设计 > 正文

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

2019-11-08 02:44:31
字体:
来源:转载
供稿:网友

题目链接在此。

题意理解

将给定的字符串按照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;}

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


上一篇:棋盘问题

下一篇:wpf之旅

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表