【PAT (Basic Level) Practice】(天梯赛)1027 打印沙漏(20分)(递归法)
题目:
题目链接
1027 打印沙漏 (20 分)本题要求你写个程序把给定的符号打印成沙漏的形状。例如给定17个“*”,要求按下列格式打印
***** *** * *** *****
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。
给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
输入格式:
输入在一行给出1个正整数N(≤1000)和一个符号,中间以空格分隔。
输出格式:
首先打印出由给定符号组成的最大的沙漏形状,最后在一行中输出剩下没用掉的符号数。
输入样例:
19 *
输出样例:
***** *** * *** ***** 2
题目分析:
输出:
为简化题目,我们只分析上三角。以上三角最底下一行为第一行,向上分析有
***** //第三行:0个空格 5个符号
*** //第二行:1个空格 3个符号
* //第一行:2个空格 1个符号
总结规律:在总共(n)行的三角中,第(i)行有(n-i)个空格,有(2*i-1)个符号
下三角同理。
计算行数:
运用递归的对称,我们只需计算上三角的行数。
关键:第一层上下三角重合,需特判
代码:
#include<iostream>
using namespace std;
void Print(int row, int index, char op);
int main()
{
int N, row = 0;
char op;
cin>>N>>op;
//第一层特判
if(N>0)
{
row = 1;
N--;
}
//当数量充足,增加行数
while(N>=2*(2*row+1))
{
N -= 2*(row*2+1);
row++;
}
Print(row,row,op);
cout<<N;
return 0;
}
void Print(int row, int index, char op)
{
//递归出口
if(index<=0) return ;
for(int i=0;i<row-index;i++) cout<<" ";
for(int i=0;i<2*index-1;i++) cout<<op;
cout<<endl;
Print(row, index-1, op);
//if判断避免第一层重复输出
if(index>1)
{
for(int i=0;i<row-index;i++) cout<<" ";
for(int i=0;i<2*index-1;i++) cout<<op;
cout<<endl;
}
}