PAT 乙级 1027 打印沙漏 v1.0
1. 题目简述及在线测试位置
1.1 给定N个字符,要求使用尽可能多的字符打印出一个沙漏。沙漏定义:每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等
1.2 在线测试位置:PAT 1027 打印沙漏
2. 基本思路
2.1 先找到规律:多少个字符能组成一个沙漏? 最小的沙漏由1个字符组成,次小的沙漏 = 最小的 + (1+2×1)×2 ,以此类推,得到 沙漏字符数 = 前一个沙漏字符数 + (1+2×i)×2 (i=1,2,3…)
2.2 把沙漏分为上下部分,分别进行打印。沙漏顶层的字符数就是 1+2×i(确定沙漏最大字符数同时,确定i的大小)
Count=1; i=1;
//退出循环时,Count值就是形成沙漏的最大字符数,i--就是沙漏的层数
while( (Count+(1+2*i)*2) <= Number )
Count += (1+2*i++)*2;
2.3 已知每行的字符数(根据相邻两行符号数差2推导)和 沙漏顶层的字符数,就可以推导出每行需要打印的空格数
SpaceNumber = (1 + 2 * i - m) / 2;
2.4 注意:需要打印剩下没用掉的符号数, 剩下为0时 也要输出
3. 完整AC代码
#include <iostream>
using namespace std;
int main()
{
int Number, Count = 1, SpaceNumber = 0;
char Symbol;
int i = 1;
cin >> Number >> Symbol;
while( (Count+(1+2*i)*2) <= Number )
Count += (1+2*i++)*2;
i--; //打印上半部分 i--就是沙漏的层数
for (int m = 1 + 2 * i; m >= 1; m -= 2) //m: 沙漏上半部分每行的字符数
{
int n=m;
SpaceNumber = (1 + 2 * i - m) / 2; //空格数。打印前半部分即可,否则会触发格式错误
while (SpaceNumber--)
cout << " ";
while (n--)
cout << Symbol;
cout << endl;
}
//打印下半部分
for (int m = 3; m<= 1 + 2 * i; m += 2)
{
int n = m;
SpaceNumber = (1 + 2 * i - m) / 2;
while (SpaceNumber--)
cout << " ";
while (n--)
cout << Symbol;
cout << endl;
}
cout << Number - Count; //最后在一行中输出剩下没用掉的符号数, 0 也要输出
return 0;
}