偶然浏览间看见大神的问题,菜鸟也试着动脑经想了想
题目:
把给定的符号打印成沙漏的形状,
所谓“沙漏形状”,是指每行输出奇数个符号;各行符号中心对齐;相邻两行符号数差2;符号数先从大到小顺序递减到1,再从小到大顺序递增;首尾符号数相等。
给定任意N个符号,不一定能正好组成一个沙漏。要求打印出的沙漏能用掉尽可能多的符号。
输入格式:整数+空格+字符
并显示用了多少符号数,剩余多少符号
代码如下:
public void printSandGlass()
{
string arr = Console.ReadLine();
string[] arrs = arr.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
//粗糙判定非法输入
if (arrs.Length != 2)
{
Console.WriteLine("Error Input");
return;
}
//使用的字符数
int number = Convert.ToInt32(arrs[0]);
//使用的字符
char sign = Convert.ToChar(arrs[1]);
int count=0;
//算出层数
int n = compute(number, out count);
Console.WriteLine("需要{0}颗{1},余{2}", count, sign, number - count);
int x = 0;
//是否过半打印
bool key = true;
/*
* 这里只打印了左边的空白,右边的空白是没有打印的
* =========================
* 注:这里每一层的打印都是由X来控制的,
* 上半部分,X递增
* 下半部分,X递减
* 由于沙漏的上半部的每一层字符个数为a.1=1 d=2的等差数列的数
* 所以每层的字符数为 2*n(层数)-1
*/
while (x >= 0)
{
//打印空白
painting(x, ' ');
//计算一层特殊符号的个数
int solid = 2 * (n - x) - 1;
painting(solid, sign, 1);
//打印过半的提示
if (solid == 1)
key = false;
if (key)
x++;
else
x--;
}
}
/// <summary>
/// 计算层数
/// 暴力破解,从1到N的平方值
/// number = n^2 -1
/// </summary>
/// <param name="number">字符数</param>
/// <param name="count">沙漏最大字符数</param>
/// <returns>三角型层数,也就是等差数的个数</returns>
int compute(int number,out int count)
{
int n=0;
while (n * n * 2 - 1 <= number)
{
n += 1;
}
count = (int)Math.Pow(n-1,2)*2-1;
return n-1;
}
/// <summary>
/// 打印字符
/// 这里采用的是逐个字符打印,也可以拼接字符为字符串,然后打印。
/// </summary>
/// <param name="number">打印的数量</param>
/// <param name="sign">打印的字符</param>
/// <param name="key">打印完成后是否换行</param>
void painting(int number,char sign,int key=0)
{
for (int i = 0; i < number; i++)
{
Console.Write(sign);
}
if (key != 0)
Console.WriteLine();//换行
}
}