十字架问题

博客围绕小A定义的十字架输出方式展开,给定n值输出对应图形。当n≥2时,需复制n-1时的图像并粘贴到上下左右。解决策略包括使用memset函数,将非“o”位置改为空格,还介绍了方法体和主方法的书写,通过观察规律确定图形中心位置来实现复制。

问题描述

小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:原图形被复制后的中心与原图中心距离

nm
1
21
33
49
527

所以可以发现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);
	}
}

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

bx
11
22
35
414
541

可以发现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;
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值