标签:分治、递归、字符串
【题解】
最终图腾是由多个与之相似的更小的图腾元素组成,一直迭代就行。我的思路先手动设置最小的三角形图腾,然后往右边和上边移动一次就形成大一级的图腾。以此类推。
不用理会题目输入的数字和图腾的大小有什么具体关系,题目都说了此大小非彼大小,只要知道2是基础三角形平移后的三角形图腾,3是把前面平移后的三角形图腾再平移一次得到更大的三角形图腾,以此类推。
【代码】
- 方法一
以左上角为原点建立坐标轴,即ch的下标。但是是从左下角往右边和上边开始迭代。
#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的下标。同时也从左下角往右边和上边开始迭代。(其实和方法一差不多,只是下标更好找,也更好理解)
#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;
}