zoukankan      html  css  js  c++  java
  • UVa 177

    链接:

    https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=113

    题意:

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

    分析:

     

    如图所示,圆圈A,B表示展开时的旋转点,其余字母代表线段。
    看图找规律。线段位置变化顺序是:左上 -> 右上 -> 右下 -> 左下 -> 左上
    当以B为旋转点(第三次展开)时。B左边的第一条线段是一条横线(即e),
    而且所有旋转点左边的第一条线段都是横线。
    因为B的左边部分是由B的下边部分旋转得来,所以其余线段可根据上面的线段位置变化顺序得出:
    因为c在d的右下方,所以e的下一条线段(即f)在e的左下方。
    因为b在c的右下方,所以f的下一条线段(即g)在f的左下方。
    因为a在b的左下方,所以g的下一条线段(即h)在g的左上方。
    依照此规律就可以生成一条完整的曲线了。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 
     4 const int dr[8] = {1, 0, 1, 0, 0, -1, 0, -1};
     5 const int dc[8] = {1, 1, -1, -1, -1, -1, 1, 1};
     6 const char dch[8+5] = "||||____";
     7 
     8 struct COORDINATE {
     9     int r, c; //行坐标,列坐标
    10 } a[9999]; //生成的线段序列,可以看作一个栈
    11 
    12 char s[300][300]; //用一个二维数组保存图像
    13 int p, sr, tr, sc, tc[300]; //栈顶指针,图像的开始行,结束行,开始列,每一行的结束列
    14 
    15 void init(){
    16     memset(s, ' ', sizeof(s));
    17     memset(tc, 0, sizeof(tc));
    18     a[0] = (COORDINATE){150, 150};
    19     a[1] = (COORDINATE){150, 151};
    20     s[a[0].r][a[0].c] = '_';
    21     s[a[1].r][a[1].c] = '|';
    22     p = 2;  sr = a[0].r;  tr = a[1].r;  sc = a[0].c;  tc[tr] = a[1].c;
    23 }
    24 
    25 void make(int r, int c, char ch){
    26     a[p] = (COORDINATE){r, c};
    27     s[a[p].r][a[p].c] = ch;
    28     if(sr > r) sr = r;
    29     if(tr < r) tr = r;
    30     if(sc > c) sc = c;
    31     if(tc[r] < c) tc[r] = c;
    32     p++;
    33 }
    34 
    35 void dfs(int d, int dep){
    36     if(d > dep) return;
    37     make(a[p-1].r - 1, a[p-1].c - 1, '_');
    38     for(int i = p - 2; i > 0; i--){
    39         COORDINATE R = a[i], L = a[i-1];
    40         int d = (s[R.r][R.c] == '_') * 4 + (R.r == L.r) * 2 + (R.c > L.c); //判断下一条线段的位置
    41         make(a[p-1].r + dr[d], a[p-1].c + dc[d], dch[d]);
    42     }
    43     dfs(d + 1, dep); //下一次展开
    44 }
    45 
    46 int main(){
    47     int n;
    48     while(scanf("%d", &n) && n){
    49         init();
    50         dfs(2, n);
    51         for(int r = sr; r <= tr; r++){
    52             for(int c = sc; c <= tc[r]; c++) printf("%c", s[r][c]);
    53             printf("
    ");
    54         }
    55         printf("^
    ");
    56     }
    57     return 0;
    58 }
  • 相关阅读:
    Mybatis <set>标签
    Mybatis <where>标签
    Mybatis choose (when, otherwise)标签
    Mybatis <if>标签
    Mybatis <Sql>标签
    Mybatis配置详解
    [转]在浏览器的标签页显示网站标志图标(或指定图标)的方法
    【转】如何建立一个样式新颖的CSS3搜索框
    【转】css布局居中和CSS内容居中区别和对应DIV CSS代码
    作业:按钮控制打开关闭新窗口及新窗口按钮关闭父窗口
  • 原文地址:https://www.cnblogs.com/hkxy125/p/8331773.html
Copyright © 2011-2022 走看看