有趣的分形圖形-遞迴和數學方法解決-POJ 2083

來源:互聯網
上載者:User

Description

A fractal is an object or quantity that displays self-similarity, in a somewhat technical sense, on all scales. The object need not exhibit exactly the same structure at all scales, but the same "type" of structures must appear on all scales. 
A box fractal is defined as below : 
  • A box fractal of degree 1 is simply 
  • A box fractal of degree 2 is 
    X X 

    X X 
  • If using B(n - 1) to represent the box fractal of degree n - 1, then a box fractal of degree n is defined recursively as following 
    B(n - 1)        B(n - 1)        B(n - 1)B(n - 1)        B(n - 1)

Your task is to draw a box fractal of degree n.

Input

The input consists of several test cases. Each line of the input contains a positive integer n which is no greater than 7. The last line of input is a negative integer −1 indicating the end of input.

Output

For each test case, output the box fractal using the 'X' notation. Please notice that 'X' is an uppercase letter. Print a line with only a single dash after each test case.

Sample Input

1234-1

Sample Output

X-X X XX X-X X   X X X     XX X   X X   X X    X   X XX X   X X X     XX X   X X-X X   X X         X X   X X X     X           X     XX X   X X         X X   X X   X X               X X    X                 X   X X               X XX X   X X         X X   X X X     X           X     XX X   X X         X X   X X         X X   X X          X     X         X X   X X            X X             X            X X         X X   X X          X     X         X X   X XX X   X X         X X   X X X     X           X     XX X   X X         X X   X X   X X               X X    X                 X   X X               X XX X   X X         X X   X X X     X           X     XX X   X X         X X   X X


一遞迴:

先看下較為常規的遞迴解決:

由於圖形是重複的,小的圖形只是把大圖形的左上方一部分輸出,,只計算最大的圖形,打表可加快速度。

#include <stdio.h>#include <string.h>int p[8] = {1,3,9,27,81,243,729};char map[730][730];//n當前的圖形大小,x,y圖形所在的座標void print(int n,int x,int y){if(n == 0){map[x][y] = 'X'; //return;}print(n-1, x, y); //左上print(n-1, x+2*p[n-1], y); //右上print(n-1, x+p[n-1], y+p[n-1]); //中間print(n-1, x, y+2*p[n-1]);print(n-1, x+2*p[n-1],  y+2*p[n-1]);}int n;int main(){for(int i=0; i<p[6]; i++) memset(map[i], 32, p[6]);print(6, 0, 0); //打表while(scanf("%d", &n) && n-- >= 0){for(int i=0; i<p[n]; i++){map[i][p[n]]=0;puts(map[i]);map[i][p[n]]=' ';}puts("-");}return 0;}

二 數學方法

在discuss裡面看到這個短小精悍的程式。

#include"stdio.h"#include"math.h"main(){int i,j,n,ii,jj,k;while(scanf("%d",&n)&&n--!=-1){for(i=0;i<pow(3,n);i++,printf("\n"))for(j=0;j<pow(3,n);j++){for(ii=i,jj=j,k=0;k<n&&(ii%3+jj%3)%2==0;ii/=3,jj/=3,k++);printf("%c",32+56*(k==n));}printf("-\n");} }

以下摘自 http://www.matrix67.com 部落格:

關於這個圖形,還可以用來證明

尋找1/5
+ 1/25 + 1/125 + .. = 1/4的圖形證明

  

    前段時間,網上湧現出一大批關於1/4 + 1/16 + 1/64 + ... = 1/3的圖形證明(1) (2)。不過,有多少人想過,為什麼這些圖形都是證明底數為1/4的情況呢?同樣是幾何級數求和,能否構造一個圖形來證明1/5
+ 1/25 + 1/125 + .. = 1/4呢?


  

    無妨讓我們來嘗試一下。絕大多數人的第一想法便是畫一個正五邊形,然後把它分成五等分。接下來,把其中一份塗上顏色,表示整個面積的1/5。然後呢?然後怎麼辦?我們需要有一種辦法把剩下的四塊中的其中一塊再次分成五份,選取一份表示1/25,並且遞迴地做下去。我們似乎發現了問題:這個“遞迴”是做不下去的。為了能夠遞迴地表示出1/5、1/25、1/125,你必須把一個正五邊形分成五個小的正五邊形,再把小正五邊形分成更小的五個正五邊形,而這似乎是做不到的。這也就是上面的那些圖形都可以用來證明Σ(1/4)^n=1/3的根本原因:它們可以把自己分成更小的四個自己,從而能夠遞迴地表示(1/4)^n。
    現在,我們的問題就出來了:為了弄出一個Σ(1/5)^n=1/4的圖形證明,我們必須尋找這樣一種圖形,它能把自身分割為五塊相同的部分,每一部分都和自身相似。

    我們能否找到這樣的圖形呢?不能!根本原因在於:一個平面圖形是二維的。平面圖形的維度決定了這樣一個性質:兩個相似圖形的相似比和面積比成平方關係。如果一個正方形的邊長是另一個正方形邊長的兩倍,那前者的面積就是後者的四倍;圓的面積必然與半徑r成平方關係,最多再乘上一個常係數。類似地,把一條曲線放大一倍,其長度也會跟著變大一倍;把一個三維圖形放大一倍,其體積將變大到原來的八倍。因此,把一個平面圖形分成四個和自身相似的圖形是相當和諧的——面積變為原來的1/4,邊長就應該變為原來的1/2,而兩個1/2邊長正好就拼成一個原邊長。但是,如果要想把一個平面圖形分成五等份,每一份的面積就應該是1/5,則對應邊應該變為原來的1/sqrt(5),這樣顯然無法既無重複又無遺漏地填滿原圖形的邊。看來,圖形證明Σ(1/5)^n=1/4似乎就不可能了。

    思考問題時要善於用想象來替代放棄。二維空間中可以證明Σ(1/4)^n=1/3。類似地,一維空間中還可以輕易證明Σ(1/2)^n=1。要是有一個什麼東西是log(5)/log(2)維的就好了——這樣的話,對應邊擴大到原來的2倍,“面積”就會變成原來的2^(log(5)/log(2))倍,也就是5倍。這就是說,在log(5)/log(2)維的“空間”裡,一個“圖形”恰好可以包含5個與自身相似的“圖形”,並且新的“邊長”正好能整除原來的“邊長”。看到這裡有人會哈哈大笑起來——這種維度會有嗎?
    有。很多分形圖形都有一些極其怪異的性質,相似比的變化和其所佔空間的變化不成整次冪的關係。例如,大名鼎鼎的分形圖形Sierpinski三角形就是這樣——相似比為1/2,所佔空間之比為1/3。一個圖形有二維圖形的樣子,卻沒有二維圖形的性質。Hausdorff維度就是專門用來處理這類問題的。我們常常用Hausdorff維度來描述一個分形圖形,比如Sierpinski三角形的Hausdorff維度就是log(3)/log(2)——所佔面積變為原來的三倍時,對應邊變為原來的兩倍。

    嘿!那麼,是不是Sierpinski三角形就可以用來證明Σ(1/3)^n=1/2呢?對!一個Sierpinski三角形由三個與自身相似的小Sierpinski三角形組成,因此你可以遞迴地表示出(1/3)^n。畫出整個Sierpinski三角形的1/3,以及另外1/3的其中1/3,以及1/3的1/3的1/3,這樣無限畫下去,你會很快看出來,總地區正好佔了原來的一半。

  

    類似地,把Sierpinski地毯放大到原來的三倍,整個圖形所佔空間就變成了原來的八倍。它的Hausdorff維度就是log(8)/log(3)。於是,我們就能用它來證明Σ(1/8)^n=1/7。

  

    回到本文最初的問題,為了證明Σ(1/5)^n=1/4,我們只需要找到這樣一個分形圖形,其Hausdorff維度分子為log(5)。這樣的圖形不僅存在,而且還不止一個。大家可以在這個頁面裡找到各種不同Hausdorff維度圖形。我找到了一個有趣的分形圖形叫做Vicsek雪花,它的Hausdorff維度是log(5)/log(3)。

     

    不斷選出更小意義上的那個1/5,你會一眼看出,選出部分的總和就是整個圖形的1/4。

     

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.