POJ 2083 Fractal 分形题目

本文通过解析Pojfractal题目,详细介绍了分治策略的实现过程。从递归分解到终态解决,再到合并结果,展示了如何利用递归思想解决复杂图形绘制问题,并附带完整代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这两天自学了一线算法导论里分治策略的内容,秉着只有真正投入投入编程,才能更好的理解一种算法的思想的想法,兴致勃勃地找一些入门的题来学习。

搜了一下最后把目光锁定在了Poj fractal这一个题上。以前一直对这种题无从下手,通过对这一条题的分析与理解,算是第一次对分治思想有一个较为具象的了解。

分治思想的依托为递归。

下面我尝试用分支策略的思想描述这一题。

分解:

在这条题里,通过分析题目可以知道:每一个更大一点的图形都是由前一个状态的小图形放置在对应位置组成的;而每一个小图形的又由更前一个状态的图形组成。

因此,我们可以把一开始输入的规模m视为【大问题】,大问题的内容是:如何按照‘X'的形态填充对应位置的字符。

接着,把大问题划分为5个规模为m-1视为【大问题的划分问题1】,问题1 的内容是:如何按照‘X'的形态填充对应位置的字符。

再接着,把问题1的内容划分为更小的5个规模为m-2的【问题1的划分问题2】,问题2 的内容是:如何按照‘X'的形态填充对应位置的字符。

……

终态:当问题被划分为为规模为1 的子问题时,已经不那么再继续划分了。这时候可以直接在当前位置上填一个“X"。

将每一个层次的问题视为一个状态, 相邻状态的关系为【当前问题规模数=前一个问题规模数-1】

解决:

通过观察每一个规模的图形不难发现其中的规律

XXXOOOXXX

XXXOOOXXX

XXXOOOXXX

OOOXXXOOO

OOOXXXOOO

OOOXXXOOO

XXXOOOXXX

XXXOOOXXX

XXXOOOXXX

每一个图形的规模面积为m*m,长与宽正好是规模数m,在左上、右上、中部、左下、右下分别为前一个规模的图形,其他部分为空

而每一个规模为m的图形,某一个部分离相邻一个部分的距离为3^(m-2)【比如左上部分第一个格子的位置距离右上部分第一个格子的距离:纵坐标相同,横坐标为+3^(m-2)】

合并:

以递归的方式合并不断分解问题,局部解决以后又返回上一个状态。

注:因为其他部分为空,所以图形以外的数组部分要填'\0'

具体实现

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 char a[1000][1000];
 7 void dfs(int cur,int x,int y)
 8 {
 9     if(cur==1)
10     {
11         a[x][y]='X';
12         return ;
13     }
14     int s=(int)pow(3.0,cur-2);
15     //分别打印左上、右上、中间、左下、右下x应该变为的图形
16     dfs(cur-1,x,y);
17     dfs(cur-1,x,y+2*s);
18     dfs(cur-1,x+s,y+s);
19     dfs(cur-1,x+2*s,y);
20     dfs(cur-1,x+2*s,y+2*s);
21 }
22 int main()
23 {
24     int n;
25     while(~scanf("%d",&n))
26     {
27         if(n==-1) break;
28         memset(a,' ',sizeof(a));
29         dfs(n,1,1);
30         int s=(int)pow(3.0,n-1);
31         for(int i=1;i<=s;i++)
32         {
33             a[i][s+1]='\0';//3的n-1次方后面没有多余空格
34 
35         }
36         for(int i=1;i<=s;i++)
37         {
38             printf("%s\n",a[i]+1);
39         }
40         printf("-\n");
41     }
42     return 0;
43 }

 

详解代码

 

转载于:https://www.cnblogs.com/AKsnoopy/p/8540478.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值