【洛谷】P1498 南蛮图腾(分治、递归)

题目:https://www.luogu.org/problem/P1498

标签:分治、递归、字符串

【题解】

最终图腾是由多个与之相似的更小的图腾元素组成,一直迭代就行。我的思路先手动设置最小的三角形图腾,然后往右边和上边移动一次就形成大一级的图腾。以此类推。

不用理会题目输入的数字和图腾的大小有什么具体关系,题目都说了此大小非彼大小,只要知道2是基础三角形平移后的三角形图腾,3是把前面平移后的三角形图腾再平移一次得到更大的三角形图腾,以此类推。

【代码】

  • 方法一

以左上角为原点建立坐标轴,即ch的下标。但是是从左下角往右边和上边开始迭代。
Snipaste_2019-09-11_22-06-23.png

#include <iostream>
#include <cmath>
using namespace std;
char ch[1050][1050];
int n, width, height;

void right(int d)	//向右平移
{
	for (int i = height; i >= height - pow(2, d) + 1; i--)
		for (int j = width/2 + 1; j <= width; j++)
		{
			ch[i][j] = ch[i][j - width / 2];
		}
}

void up(int d)	//向上平移
{
	for (int i = height - int(pow(2,d)); i >= height - int(pow(2, d+1)) + 1; i--)
		for (int j = width / 4 + 1; j <= width * 3 / 4; j++)
		{
			ch[i][j] = ch[i + int(pow(2, d))][j - width / 4];
		}
} 

int main()
{
	cin >> n;
	int x = int(pow(2, n));
	int y = 1;
	ch[x][y] = ch[x - 1][y + 1] = '/';
	ch[x][y + 1] = ch[x][y + 2] = '_';
	ch[x][y + 3] = ch[x - 1][y + 2] = '\\';

	height = int(pow(2, n));
	width = 4;
	for (int i = 1; i <= n-1; i++)
	{
		width *= 2;
		right(i);
		up(i);
	}

	for (int i = 1; i <= height; i++)
	{
		for (int j = 1; j <= width; j++)
		{
			if (ch[i][j] == '\0')	cout << ' ';
			else    cout << ch[i][j];
		}
		cout << endl;
	}
	return 0;
}
  • 方法二

用方法一做完才发现,为什么要逆向来做呢,这不是麻烦吗 ?,完全可以正向来做。

以左下角为原点建立坐标轴,即ch的下标。同时也从左下角往右边和上边开始迭代。(其实和方法一差不多,只是下标更好找,也更好理解)
Snipaste_2019-09-11_22-08-24.png

#include <iostream>
#include <cmath>
using namespace std;
char ch[1050][1050];
int n, width, height;

void right()	//向右平移
{
	for (int i = 1; i <= height; i++)
		for (int j = width +1; j <= width * 2; j++)
		{
			ch[i][j] = ch[i][j - width];
		}
}

void up()	//向上平移
{
	for (int i = height + 1; i <= height * 2; i++)
		for (int j = width / 2 + 1; j <= width * 3 / 2; j++)
		{
			ch[i][j] = ch[i - height][j - width / 2];
		}
}

int main()
{
	cin >> n;
	ch[1][1] = ch[2][2] = '/';
	ch[1][2] = ch[1][3] = '_';
	ch[1][4] = ch[2][3] = '\\';

	height = 2;
	width = 4;
	for (int i = 2; i <= n; i++)
	{
		right();
		up();
		width *= 2;
		height *= 2;
	}

	for (int i = height; i >= 1; i--)
	{
		for (int j = 1; j <= width; j++)
		{
			if (ch[i][j] == '\0')	cout << ' ';
			else    cout << ch[i][j];
		}
		cout << endl;
	}
	return 0;
}
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值