这是我参与「第四届青训营 」笔记创作活动的第3天
分治
1.题目描述
自从到了南蛮之地,孔明不仅把孟获收拾的服服帖帖,而且还发现了不少少数民族的智慧,他发现少数民族的图腾往往有着一种分形的效果,在得到了酋长的传授后,孔明掌握了不少绘图技术,但唯独不会画他们的图腾,于是他找上了你的爷爷的爷爷的爷爷的爷爷……帮忙,作为一个好孙子的孙子的孙子的孙子……你能做到吗?
输入格式
每个数据一个数字,表示图腾的大小(此大小非彼大小) n<=10
输出格式
这个大小的图腾
数据范围
对于所有的数据,n<=10
2.分析
分治:由此题可发现,输出结果是具有形态相似这个特性的,最终的图腾是由与之相似的更小的图腾组成,我们找到最小的图腾。以此类推,因为n-1规模图腾可以生成n规模的图腾,我们可以用分治法解决更大规模的图腾,并把n=1的基础图腾预先输入。
3.证明
通过题目的描述,我们很快便能发现规律,将原始图腾不断的向下,向右复制,就可以得到大一号的图腾,直到得到我们需要的大小的图腾。
4.代码
#include<iostream>
#include<cstring>
using namespace std;
int n;
char a[3000][3000];
int h=2,w=4;//h是高,w是宽
int main(){
cin>>n;
memset(a,' ',sizeof(a));
a[1][1]=a[1][4]=' ';
a[1][2]=a[2][1]='/';
a[1][3]=a[2][4]='\\';//向右的划线有特殊的含义
a[2][2]=a[2][3]='_';
for(int i=1;i<n;i++){
//向下和向右
for(int j=1;j<=h;j++){
for(int k=1;k<=w;k++){
a[j+h][k]=a[j+h][k+w]=a[j][k];
a[j][k]=' ';//把上面的清掉
}
}
//向上
for(int j=1;j<=h;j++){
for(int k=1;k<=w;k++){
a[j][k+w/2]=a[j+h][k];
}
}
w*=2;h*=2;
//刷新完成一次
}
for(int i=1;i<=h;i++){
for(int j=1;j<=w;j++){
cout<<a[i][j];
}
cout<<endl;
}
return 0;
}
5.复杂度分析
每循环一次,w、h自乘2,计算过后,最终的时间复杂度为O(4^n)。