递归图形输出问题通用解法

 ACM学了有一段时间了,有一类题目遇到过了很多次,但很少做出来,这类题目就是递归图形输出。找了一些大神博客学习了一下,在这里做个总结。

 那什么是递归图形输出问题呢?顾名思义,按照某种递归的规律输出某种类型图形的n次递归后的图形。

 比如:

n=0:

 

n=1:

n=2:



n=3:



现在问你当n=7的时候这个图形是什么样子的。这种要求输出按某种规律递归增长的图形的问题就是递归图形输出问题。

再比如说POJ-1941也是一道典型的递归图形输出,链接->https://vjudge.net/problem/POJ-1941

 这一类问题全部有一套通用的解法:

1,找n次递归增长后的图形的中点。

2,根据图形增长的规律找到所有子图形的中点。

3,对子图形递归找子图形的中点。

4,直到n=0后,对当前点的位置做标记,用二维数组存。

5,遍历二维数组输出图形。

就比如说我举的那个例子解题代码如下:

#include <iostream>  
#include <cstdio>  
#include <cstring>  
#include <string>  
#include <cstdlib>  
#include <cmath>  
#include <vector>  
#include <queue>  
#include <iterator>  
#include <map>  
#include <algorithm>  
#include <set>  
#include <functional>  
#include <time.h>  
#define lson rt<<1  
#define rson rt<<1|1  
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 1e9 + 5;
const int MAXN = 100005;
const LL MOD = 1000000007;
const double eps = 1e-8;
const double PI = acos(-1.0);
LL gcd(LL a, LL b) { return b == 0 ? a : gcd(b, a%b); }
LL ppow(LL a, LL b) { LL res = 1; for (int i = 1; i <= b; i++)   res *= a; return res; }
LL quick_mod(LL a, LL b, LL c) { LL ans = 1; while (b) { if (b % 2 == 1)ans = (ans*a) % c; b /= 2; a = (a*a) % c; }return ans; }

bool MAP[3000][3000];//二维数组存每个点是输出0还是空格

void draw(int x, int y, int n)//画图函数
{
	int res;
	if (n == 0)
		MAP[x][y] = true;//n=0的时候就是一个点,标记为要输出0
	else
	{
		res = ppow(3, n - 1);
		draw(x, y, n - 1);//每一个图由五个子图构成,对五个子图递归调用draw函数
		draw(x - res, y + res, n - 1);
		draw(x - res, y - res, n - 1);
		draw(x + res, y + res, n - 1);
		draw(x + res, y - res, n - 1);
	}
}

int main()
{
	int n, x;
	while (scanf("%d",&n)!=EOF)
	{
		memset(MAP, 0, sizeof MAP);
		x = (ppow(3, n) + 1) / 2;
		draw(x, x, n);
		for (int i = 1; i <= x*2-1; i++)//遍历二维数组输出
		{
			for (int j = 1; j <= x*2-1; j++)
			{
				if (MAP[i][j])
					printf("0");
				else
					printf(" ");
			}
			printf("\n");
		}
	}
}




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值