【题解】【洛谷P1498】【分治】——南蛮图腾

南蛮图腾

通往洛谷的传送门

题目背景

自从到了南蛮之地,孔明不仅把孟获收拾的服服帖帖,而且还发现了不少少数民族的智慧,他发现少数民族的图腾往往有着一种分形的效果,在得到了酋长的传授后,孔明掌握了不少绘图技术,但唯独不会画他们的图腾,于是他找上了你的爷爷的爷爷的爷爷的爷爷……帮忙,作为一个好孙子的孙子的孙子的孙子……你能做到吗?

题目描述

给定一个正整数 n n n,参考输出样例,输出图形。

输入格式

每个数据输入一个正整数 n n n,表示图腾的大小(此大小非彼大小)

输出格式

这个大小的图腾

输入输出样例

输入 #1

2

输出 #1

   /\
  /__\
 /\  /\
/__\/__\

输入 #2

3

输出 #2

       /\
      /__\
     /\  /\
    /__\/__\
   /\      /\
  /__\    /__\
 /\  /\  /\  /\
/__\/__\/__\/__\

提示

数据保证, 1 ≤ n ≤ 10 1 \leq n \leq 10 1n10

1.题意解析

    乍一看,这一道题似乎无从下手。

    容易发现,每一个规模为n的图形都是由三个规模为n-1的图形演变过来的。于是,我们可以考虑使用分治求解。

    首先定义一个函数draw(deep,x,y),表示在 ( x , y ) (x,y) (x,y)(绘制图形第一行/的位置)处绘制一个规模为deep的图形。

    接下来,我们就要开始研究规律了。对于一个规模为deep的图形,最上面的那个规模为n-1的图形和它的坐标一样,即draw(deep-1,x,y)

    对于左下方的图形,和右下方的图形,它们的坐标分别为 ( ( x + 2 d e e p − 1 , y − 2 d e e p − 1 ) ((x+2^{deep-1},y-2^{deep-1}) ((x+2deep1,y2deep1) ( x + 2 d e e p − 1 , y + 2 d e e p − 1 ) (x+2^{deep-1},y+2^{deep-1}) (x+2deep1,y+2deep1)。请先自行思考,如果不会的话请参考【附录-提示】。

    最后是递归边界。容易发现,最小的三角形是这个:

 /\
/__\

    只需要直接输出即可。注意,输出\时,由于其特性(转义字符),需要这样输出:\\

2.AC代码

#include<bits/stdc++.h>
using namespace std;
#define MAXN 3010
char a[MAXN][MAXN];//存储图腾
int n;
void draw(int deep,int x,int y)
//绘制图腾,x代表第一个字符'/'行数,y代表其列数,deep代表绘制规模
{
	if(deep==1)//递归边界,绘制规模为1的三角形
	{
		a[x][y]='/';a[x][y+1]='\\';//绘制第x行
		a[x+1][y-1]='/';a[x+1][y]=a[x+1][y+1]='_';a[x+1][y+2]='\\';//绘制第x+1行
		return;//返回
	}
	//将规模为n的问题转换成三个规模为n-1的问题
	draw(deep-1,x,y);//绘制上面的图腾
	draw(deep-1,x+(1<<deep-1),y-(1<<deep-1));//绘制下面左边的图腾
	draw(deep-1,x+(1<<deep-1),y+(1<<deep-1));//绘制下面右边的图腾
}
void print()//打印图腾 
{
	for(int i=1;i<=1<<n;i++)
	{
		for(int j=1;j<=(1<<n)+i;j++)
	        if(a[i][j]!=0)cout<<a[i][j];//注意全局变量会被初始化为0
	        else cout<<' ';
	    puts("");
	}
}
int main()
{
    cin>>n;
    draw(n,1,1<<n);//绘制图腾
    print();//打印
	return 0;
}

3.附录-提示

    真的不再思考一下了吗?

    容易发现,每个小三角形的占用宽度和高度都为2。每增加一个规模,宽度和高度都会*2。再试着思考一下吧。

    如果还不会的话,可以自己代数尝试理解。

喜欢就订阅此专辑吧!

【蓝胖子编程教育简介】
蓝胖子编程教育,是一家面向青少年的编程教育平台。平台为全国青少年提供最专业的编程教育服务,包括提供最新最详细的编程相关资讯、最专业的竞赛指导、最合理的课程规划等。本平台利用趣味性和互动性强的教学方式,旨在激发孩子们对编程的兴趣,培养他们的逻辑思维能力和创造力,让孩子们在轻松愉快的氛围中掌握编程知识,为未来科技人才的培养奠定坚实基础。

欢迎扫码关注蓝胖子编程教育
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

蓝胖子教编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值