算法设计|青训营笔记

112 阅读1分钟

这是我参与「第四届青训营 」笔记创作活动的第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)。