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(‘\n‘),prey = -1;
        for(int j = prey+1; j < y[id]; j++) putwchar(‘ ‘);
        putchar(decode[dir[id]]);
        prey = y[id]; prex = x[id];
    }
    printf("\n^\n");
}

int main()
{
   // freopen("out.txt","w",stdout);
    int n;
    while(scanf("%d",&n),n){
        solve(n);
    }
    return 0;
}
时间: 2024-12-29 09:34:25

UVA 177 PaperFolding 折纸痕的相关文章

例题1折纸痕

递归算法的思路,使用 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Drawing.Drawing2D; namespace 例题1折纸痕 {     

折纸问题

题目 请把一段纸条竖着放在桌子上,然后从纸条的下边向上方对折1次,压出折痕后展开.此时 折痕是凹下去的,即折痕突起的方向指向纸条的背面.如果从纸条的下边向上方连续对折2 次,压出折痕后展开,此时有三条折痕,从上到下依次是下折痕.下折痕和上折痕. 给定一 个输入参数N,代表纸条都从下边向上方连续对折N次,请从上到下打印所有折痕的方向. 例如:N=1时,打印: down :N=2时,打印: down down up 解答 本质上就是将下面这棵二叉树按照 右 -> 中 -> 左 的顺序进行遍历: p

折纸问题java实现

1 /** 2 * 折纸问题 这段代码写的太low了 本人水平有限 哎... 全是字符串了 3 * @param n 4 * @return 5 * @date 2016-10-7 6 * @author shaobn 7 */ 8 public static String[] flodpaper(int n){ 9 int length = (int)Math.pow(2,n)-1; 10 int position = (int)Math.pow(2,n-1)-1; 11 String[] s

【题解】折纸

题目描述 现有一个W×H的矩形纸张,求至少要折多少次才能使矩形纸张变成w×h的矩形纸张.注意,每次的折痕都要平行于纸张的某一条边. 输入输出格式 输入格式 第一行包括两个整数W,H. 第二行包括两个整数w,h. 输出格式 一行,输出一个整数,表示至少需要折的次数.若无解,则输出-1. 输入输出样例 输入样例一 2 7 2 2 输出样例一 2 输入样例二 5 5 1 6 输出样例二 -1 输入样例三 10 6 4 8 输出样例三 2 说明 数据规模 对于20%的数据,W=w且H,h≤3: 对于10

CSS3写折纸

<!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>折纸选项卡</title> <style> @-webkit-keyframes open { 0% { -webkit-transform:rotateX(-120deg);

关于折纸的动画

其实关于折纸的重点是在HTML和CSS的布局上主要就是要一个嵌套一个,如果不是的话,会有撑开的宽高从而难以连接在一起.不过折纸还没有写完一些兼容,也是参考视频上作的小练习 <html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>无标题</title></head><bo

【BZOJ】1074: [SCOI2007]折纸origami

http://www.lydsy.com/JudgeOnline/problem.php?id=1074 题意:一开始有一个左上角是(0,100),右下角是(100,0)的纸片,现在可以沿有向直线折n次(n<=8,右边折向左边),折完后,有m个询问(m<=50),每次询问一个点在最终的图形中穿过了几次纸片. #include <cstdio> #include <cstring> #include <cmath> #include <string>

[FZYZOJ 2162] Zrn神犇之折纸游戏

P2162 -- Zrn神犇之折纸游戏 时间限制:2000MS 内存限制:524288KB Description Zrn神犇最近喜欢上一款折纸游戏,因此他几乎每天都拿着一条悠长悠长又寂寥的纸带折来折去.其具体规则是这样的: 这是一个长度为N,宽度为1的纸条,从1开始写着连续的N个自然数. 1 2 3 4 5 6 … N 如果它的长度为偶数,Zrn神犇则会很高兴,直接把它从左往右或从右往左对折.比如长度为6的纸条从左往右对折完就会是这样: 如果它的长度为质数,Zrn神犇则会觉得不太爽,他就只能把

50种折纸方法

各种折纸方法图解 植物类 枫叶 梅花 动物类 千纸鹤的几种做法 狗狗 豹子 蛇 大象 狐狸 鹅 老鼠 猴子 骆驼 大嘴鸟 昆虫类 蜻蜓 蝎子 瓢虫 螳螂 蜜蜂 折纸图解-魔幻类 蝙蝠 巫婆 骷髅 南瓜头 小鬼魂 巫师帽子 几种纸船的做法 几种花的做法 小猫钓鱼做法 小鱼 小猫脸 来自为知笔记(Wiz)