例题 2.5 叠筐(《计算机考研机试指南》P12)
题目描述
把一个个大小差一圈的筐叠上去,由里到外看像一个一个的环
输入
输入一个三元组,分别是:外筐的尺寸 n(大于 0 小于 80 的正奇数)、中心花色字符、外围花色字符。
输出
一个叠筐的图案
示例输入
11 B A
5 @ w
示例输出
AAAAAAAAA
ABBBBBBBBBA
ABAAAAAAABA
ABABBBBBABA
ABABAAABABA
ABABABABABA
ABABAAABABA
ABABBBBBABA
ABAAAAAAABA
ABBBBBBBBBA
AAAAAAAAA
@@@
@www@
@w@w@
@www@
@@@
【分析】方法一:
找到图形构造的规律,发现其实上下左右对称的,根据规律一行一行打印输出。
方法二:
根据规律构造一个二维数组,根据规律往里面填充字符,一次填充一个圈,最后将整个二维数组打印输出。此方法整体复杂程度优于第一种。
【代码 2.5 法一】
#include <stdio.h>
#include <stack>
using namespace std;
int main(int argc, char const *argv[])
{
int h;
char centreChar,peripheralChar;
scanf("%d %c %c",&h,¢reChar,&peripheralChar);
char firstChar,endChar;
if (((h+1)/2)%2 == 0)
{
firstChar = peripheralChar;
endChar = centreChar;
}else{
firstChar = centreChar;
endChar = peripheralChar;
}
stack<char> st1;
// 循环打印上 h/2 行
for (int i = 0; i < h/2; ++i)
{
stack<char> st2;
// 打印下三角
int j = 0;
if (i == 0)
{
printf(" ");
st1.push(' ');
st2.push(' ');
++j;
}else{
for (; j <= i; ++j)
{
if (j%2 == 0)
{
printf("%c", firstChar);
st1.push(firstChar);
st2.push(firstChar);
}else{
printf("%c", endChar);
st1.push(endChar);
st2.push(endChar);
}
}
}
// 打印上三角
for (int k = i+1; k < h/2; ++k)
{
if (k != 0)
{
if (j%2 != 0)
{
printf("%c", firstChar);
st1.push(firstChar);
st2.push(firstChar);
}else{
printf("%c", endChar);
st1.push(endChar);
st2.push(endChar);
}
}
}
// 打印中间字符
if (i%2 == 0)
{
printf("%c", firstChar);
st1.push(firstChar);
}else{
printf("%c", endChar);
st1.push(endChar);
}
// 打印右边对称
while(!st2.empty()){
st1.push(st2.top());
printf("%c",st2.top());
st2.pop();
}
printf("\n");
st1.push('\n');
}
// 打印中间行
for (int i = 0; i < h; ++i)
{
if (i%2 == 0)
{
printf("%c", firstChar);
}else{
printf("%c", endChar);
}
}
while(!st1.empty()){
printf("%c", st1.top());
st1.pop();
}
printf("\n");
return 0;
}
【总结】此方法利用堆栈简化了部分代码。总体图案有行列组成,既有行对称又有列对称,对于每一行,只需要考虑左半部分,而左边又由两部分组成,可以看作是一个上三角和一个下三角。根据规律分别打印。将打印输出的字符压入一个堆栈,即可得到右半部分对称的图案。上下对称的部分同理。中间部分需要另外的逻辑单独处理。此方法逻辑较为繁琐,不推荐使用。