问题描述

小A很喜欢十字架,并喜欢用各种方式产生十字架的样子。小A不满足简单的十字架输出效果,所以重新定义了一种高大上的十字架输出方式。
给一个n(1≤n≤10) , 输出对应的图形,具体形式如下:
1.当n=1的时候,输出一个小写字母"o" :
o
2.当n≥2的时候,复制n=n-1时候的图像,并且在n-1图像的上、下、左、右都粘贴一个一模一样的图形。
如n=2时,在原图"o"的上下左右都粘贴一个"o",所以最后输出的是这样一个图形:
o
ooo
o

输入 输出
包含多组数据,第一行是数据组数T(T≤10),随后有T行,每组数据占一行,其中包含一个数字n(1 ≤ n ≤ 10) 。 首先每行输出:“Case #x:”,x表示这是第几组数据,在随后的行中输出对应图形。注意每行输出字符数应该与o处于最右的那一行的字符数相同;如果对应位置没有字母o,就在那一个位置输出一个空格。

样例输入:2 2 3
样例输出:
十字架问题

解决策略

本题主要需要被解决的问题是如何复制上一级的图形,并且将这个图形在原图形的上下左右各粘贴一个,从而形成新的图形。

memset的用法
头文件:<string.h> 或 <memory.h>
memset(结构体/数组名 , 用于替换的ASCII码对应字符 , 前n个字符 );
memset(结构体/数组名 , "用于替换的字符“ , 前n个字符 );
在本例中将使用memset函数实现:将所有除了需要输出“o”的位置改为输出“(空格)”

#include<cstring>
memset(a," ",sizeof(a));

方法体的书写
首先可以写一个方法体,便于重复调用打印输出的那一部分代码
因为涉及到二维数组,所以可以先申请一个比较大的数组空间(题目中已经有了描述,n的值最大不能超过10)(不过这不是一个好的习惯)
经过对输出图形的观察,可以发现有如下的规律
n:输入的数据 ,m:原图形被复制后的中心与原图中心距离

n m
1
2 1
3 3
4 9
5 27

所以可以发现n和m的关系是m=3(n-2)
当n=1时,仅仅打印输出一个"o",当n>1时,可以先确定各个复制后图形的中心位置,然后再复用打印部分的方法体,实现复制的工作
方法体代码如下:

#define N 1000

char a[N][N];
void print(int x,int y,int n) {
	int m = pow(3, n - 2);
	if (n == 1) {
		a[x][y] = 'o';
	}
	else {
		print(x, y, n - 1);
		print(x - m, y, n - 1);
		print(x + m, y, n - 1);
		print(x, y - m, n - 1);
		print(x, y + m, n - 1);
	}
}

然后便是写出主方法了
在这里需要判断数组的中心坐标

b x
1 1
2 2
3 5
4 14
5 41

可以发现x=3(b-2) *3/2+1/2,亦即x=3(b-2) +(3(b-2) +1)/2.因此可以据此打印出各部分中心位置的图形,然后复用方法体便可完成问题的需求
主方法代码如下:

int main() {
	int T,n;
	cin >> T;
	int c = T;
	while (T--) {
		cin >> n;
		if (n > 10) {
			return 0;
		}
		cout << "Case #" << c-T<< ":"<<endl;
		memset(a, ' ', sizeof(a));                       //重置数组中的元素,用空格替换
		int x = pow(3, n - 2) + (pow(3, n - 2) + 1) / 2;
		print(x, x, n);
		int m = pow(3, n - 1);
		for (int x = 1; x <=m; x++) {
			for (int y = 1; y <=m; y++) {
				cout << a[x][y];
			}
			cout << endl;
		}
	}
}

相关文章:

  • 2021-07-07
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-01-15
  • 2021-12-14
  • 2021-09-14
猜你喜欢
  • 2022-02-19
  • 2021-10-09
  • 2021-09-27
  • 2021-12-15
  • 2022-12-23
  • 2021-04-18
  • 2021-06-11
相关资源
相似解决方案