zoukankan      html  css  js  c++  java
  • UVA 177 PaperFolding 折纸痕 (分形,递归)

    著名的折纸问题:给你一张很大的纸,对折以后再对折,再对折……每次对折都是从右往左折,因此在折了很多次以后,原先的大纸会变成一个窄窄的纸条。现在把这个纸条沿着折纸的痕迹打开,每次都只打开“一半”,即把每个痕迹做成一个直角,那么从纸的一端沿着和纸面平行的方向看过去,会看到一条美妙的曲线。

    就是一个分形,规定一下,纸的朝向,然后不难发现规律。

    实现方面,可以迭代也可递归。

    在图形输出方面,存下x和y坐标,然后下标排个序,或者用map。

    //Rey 2015.8.3
    #include<bits/stdc++.h>
    using namespace std;
    
    // r -> rl -> open -> ru
    //   -> rlrl -> open -> r ud l -> open -> ru lu
    //   -> rlrlrlrl -> open -> r ud lr ud l -> open -> ru ludr dl -> rulu ldlu
    //   -> rlrlrlrlrlrlrlrl -> r ud lr ud lr ud lr ud l -> ru
    
    
    const int maxn = 14;
    const int maxL = (1<<13)+5;
    int dir[maxL];
    int Rotate[maxL];
    int r[maxL];
    int x[maxL],y[maxL];
    // up right down left
    // 0   1    2    3
    int dx[] = {-1,0,0, 0};
    int dy[] = { 0,1,0,-1};
    int mx[] = { 0,0,1, 0};
    int my[] = { 0,1,0,-1};
    char decode[] = {'|','_','|','_'};
    
    bool cmp(int a,int b) { return x[a] < x[b] || ( x[a] == x[b] && y[a] < y[b] ); }
    
    void solve(int n)
    {
        int N = (1<<n);
        // fold
        for(int i = 0, tmp[2] = {1,3}; i < N; i++) dir[i] = tmp[i&1];
        memset(Rotate,0,sizeof(int)*N);
        //open
        //mark
        for(int i = 1 ; i <= n; i++) {
            int seg = 1<<i;
            for(int j = 1<<(i-1); j  < N; j += seg<<1){
                    for(int k = 0; k < seg && j+k < N; k++)
                        Rotate[j+k]++;
            }
        }
    
        //rotate and calculate position
        int minx = 0,miny = 0;
        x[0] = y[0] = 0;
        for(int i = 1; i < N; i++){
            int &u = dir[i] , u2 = dir[i-1];
            u = (u + Rotate[i])%4;
            x[i] = x[i-1] + dx[u2] + mx[u] ;
            y[i] = y[i-1] + dy[u2] + my[u] ;
            minx = min(minx,x[i]);
            miny = min(miny,y[i]);
        }
        //normalize
        for(int i = 0; i < N; i++){
            x[i] -= minx;
            y[i] -= miny;
        }
    
        for(int i = 0; i < N; i++) r[i] = i;
        sort(r,r+N,cmp);
    
        int prex = 0,prey = -1;
        for(int i = 0; i < N; i++){
            int id = r[i];
            if(x[id] != prex) putchar('
    '),prey = -1;
            for(int j = prey+1; j < y[id]; j++) putwchar(' ');
            putchar(decode[dir[id]]);
            prey = y[id]; prex = x[id];
        }
        printf("
    ^
    ");
    }
    
    
    int main()
    {
       // freopen("out.txt","w",stdout);
        int n;
        while(scanf("%d",&n),n){
            solve(n);
        }
        return 0;
    }
  • 相关阅读:
    945.使数组唯一的最小增量
    用两个栈实现队列
    MySQL的约束
    数据库的设计
    约束
    DQL查询
    数据库的基本概念
    SQL基础语法
    MySQL基础
    java的注解和反射
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4699728.html
Copyright © 2011-2022 走看看