问题描述
给定正方形边长width,如图按规律输出层层嵌套的正方形图形。
注意,为让选手方便观看,下图和样例输出均使用下滑短线代替空格,请选手输出的时候使用空格而不是“_”。
width=6:
******
*____*
*_**_*
*_**_*
*____*
******
输入格式
仅一行一个整数width。
输出格式
按规律输出图形,不要输出多余空格。
样例输入
10
样例输出
**********
*________*
*_******_*
*_*____*_*
*_*_**_*_*
*_*_**_*_*
*_*____*_*
*_******_*
*________*
**********
数据规模和约定
width满足width=4n+2,n为正整数。
且width<=50。
初步构想代码如下
#include<iostream>
using namespace std;
int main()
{
int width = 0,flag=0,i;//flag用于做循环次数的标志
char a[51] = {0};//用于存储每一行除却头,尾的 * 以及中间的重复值,最后保留的对称值的一半,如width=10下的第四行*_*____*_*,此数组中存的便是_*,以便后续对称输出
cin >> width;
int temp = width;
char ch1 = ' ',ch2='*';
for (i = width; i> width / 2; i--)//先输出上半部分
{
if (i == width)//输出第一行
{
for (int j = 0; j < i;j++)
cout << "*";
cout << endl;
}
else
{
cout << "*";//输出每一行的头*
temp -= 2;//控制每一行中间相同的那一部分,如width=10下的第四行*_*____*_*,相同的便是____
flag++;
int temp1 = 0,s=0;
temp1 = width - 2 - temp;//控制对称部分的个数
for (int j = 0; j < temp1/2; j++)//输出对称部分的一半
{
if (j % 2 == 0)
{
cout << ch1;
a[s++] = ch1;
}
else
{
cout << ch2;
a[s++] = ch2;
}
}
for (int j = 0; j < temp; j++)//输出相同值的一部分
{
if (flag % 2 != 0)
cout << ch1;
else
cout << ch2;
}
for (int j = s-1; j>=0; j--)//输出对称部分另一半
{
cout << a[j];
}
cout << "*" << endl;
if (i - 1 == width / 2)//当上半部分最后一行到达时,将最后一行再输出一便
{
cout << "*";
for (int j = 0; j < s; j++)
cout << a[j];
for (int j = 0; j < temp; j++)
{
if (flag % 2 != 0)
cout << ch1;
else
cout << ch2;
}
for (int j = s-1; j>=0; j--)
cout << a[j];
cout << "*" << endl;
}
}
}
for (; ; i--)//下半部分即将控制变量temp的值逐步变回去
{
temp += 2;
if (temp >= width)//当temp=width时,到达下半部分的倒数第二行,使得循环跳出
break;
cout << "*";
flag++;
int temp1 = 0, s = 0;
temp1 = width - 2 - temp;
for (int j = 0; j < temp1 / 2; j++)
{
if (j % 2 == 0)
{
cout << ch1;
a[s++] = ch1;
}
else
{
cout << ch2;
a[s++] = ch2;
}
}
for (int j = 0; j < temp; j++)
{
if (flag % 2 != 0)
cout << ch1;
else
cout << ch2;
}
for (int j = s - 1; j >= 0; j--)
{
cout << a[j];
}
cout << "*" << endl;
}
for (int j = 0; j < width; j++)//输出下半部分的最后一行
cout << "*";
return 0;
}
输出展示为
此代码暴力易懂,但过于繁琐,想到可以将上半部分输出保存于数组中,下半部分直接输出即可,有下列改进版
#include<iostream>
using namespace std;
int main()
{
int width = 0,flag=0,i,m;
char a[51] = { 0 }, b[51][51] = {0};//用于存储上半部分
cin >> width;
int temp = width;
char ch1 = ' ',ch2='*';
for (i = width; i> width / 2; i--)
{
if (i == width)
{
for (int j = 0; j < i; j++)
{
cout << "*";
b[flag][j] = '*';
}
cout << endl;
}
else
{
cout << "*";
temp -= 2;
flag++;
m = 0;
b[flag][m++] = '*';
int temp1 = 0,s=0;
temp1 = width - 2 - temp;
for (int j = 0; j < temp1/2; j++)
{
if (j % 2 == 0)
{
cout << ch1;
a[s++] = ch1;
b[flag][m++] = ch1;
}
else
{
cout << ch2;
a[s++] = ch2;
b[flag][m++] = ch2;
}
}
for (int j = 0; j < temp; j++)
{
if (flag % 2 != 0)
{
cout << ch1;
b[flag][m++] = ch1;
}
else
{
cout << ch2;
b[flag][m++] = ch2;
}
}
for (int j = s-1; j>=0; j--)
{
cout << a[j];
b[flag][m++] = a[j];
}
cout << "*" << endl;
b[flag][m++] = '*';
}
}
for (int k = flag; k >= 0; k--)
{
for (int z = width-1; z >=0; z--)
cout << b[k][z];
cout << endl;
}
return 0;
}
以上均为学习笔记,若有错误,欢迎大家指出,一定积极讨论并予以改正