实验目的、内容及要求:
实验目的:
1.掌握分治法的基本思想
2.使用递归-分治策略求解实际问题
实验内容:
分形是一种具有自相似的现象的图形,在分形中,图形的每一组成部分都在特征上和整体相似,只是规模缩小了,一种盒子的分形定义如下:
(1)当问题规模为1时,图形为:X。
(2)当问题规模为2时,图形为:
(3)若用B(n-1)表示规模为n-1的盒子分形,则规模为n的盒子分形为:
你的任务是,给定问题规模n,输出问题规模为n的盒子分形。当n=-1时表示输入结束。
实验过程(包括实现思路、实验步骤/实现代码、实验结果/运行图):
当问题规模n>1时,输出的图形可以看作5个部分,左上方子图形、右上方子图形、中间子图形、左下方子图形、右下方子图形,这些子图形和原问题相比,性质相同,整体相似,只是规模为n-1。当问题规模为1时,直接输出X。于是问题满足递归性质,也满足分治法求解的条件。具体代码如下:
#include <iostream>
#include <cmath
using namespace std;
char** frac;//存储字符“X”,动态生成数组
int num;//问题规模
void Fractal(int n)
{
num = n;
int k = pow(3.0, num - 1);//给k赋值3的num-1次
frac = new char* [k];//动态分配k行,k列
for (int i = 0; i < k; i++)
frac[i] = new char[k];
for (int i = 0; i < k; i++)
{
for (int j = 0; j < k; j++)
frac[i][j] = ' ';//初始化为空格
}
}
void Solve(int i, int j, int n)
{
if (n == 1)
{
frac[i][j] = 'X';
return;
}
int off = pow(3.0, n - 2);//给off赋值3的num-1次方
Solve(i, j, n - 1);//得到左上方的分形
Solve(i, j + off * 2, n - 1);//得到右上方的分形
Solve(i + off, j + off, n - 1); //得到中间的分
Solve(i + off * 2, j, n - 1); //得到左下方的分形
Solve(i + off * 2, j + off * 2, n - 1); //得到右下方的分形
}
int main()
{
int n = 0;
cin >> n;
while (n != -1)
{
Fractal(n);//函数调用
Solve(0, 0, num);//函数重载
int k = pow(3.0, num - 1);//给k赋值3的num-1次方
for (int i = 0; i < k; i++)//输出“X”
{
for (int j = 0; j < k; j++)
{
cout << frac[i][j];
}
cout << "\n";
}
cout << "-\n";//一次循环结束后输出“-”
cin >> n;
for (int i = 0; i < k; i++)//释放之前我们动态生成的数组
delete[] frac[i];
delete[] frac;
}
return 0;
}