uva 177:Paper Folding(模拟 Grade D)

题目链接

题意:一张纸,每次从右往左对折。折好以后打开,让每个折痕都自然的呈90度。输出形状。

思路:模拟折……每次折想象成把一张纸分成了正面在下的一张和反面在上的一张。维护左边和方向,然后输出。细节有点多。

代码:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;

#define N (1<<13)+10

struct Paper{
    int l, r;
    bool isFace;
    Paper(){}
    Paper(int _l, int _r, bool is) : l(_l), r(_r), isFace(is){}
}paper[N];

int data[N];

int pp;

void flod(Paper &now) {
    int mid = (now.l+now.r)/2;
    data[mid] = now.isFace?1:-1;
    //printf("%d %c %d\n", now.l, "^v"[data[mid]==1], now.r);
    if( now.isFace ) {
        paper[pp++] = Paper(mid,now.r,!now.isFace);
        now.r = mid;
    } else {
        paper[pp++] = Paper(mid,now.r,now.isFace);
        now.r = mid;
        now.isFace = !now.isFace;
    }

}

struct Point{
    int x,y;
    int way;
    Point(int x=0, int y=0, int way=-1):x(x),y(y),way(way){}
}point[N];

enum{
    R,U,L,D
};

char mat[2000][2000];
void showGraph(int end) {
    point[0] = Point(0,0,R);
    //printf("%d,%d,%c\n",0,0,"RULD"[R]);
    int lmost = 0;
    int umost = 0;
    int rmost = 0;
    int dmost = 0;
    for (int i = 1; i < end; i++) {
        int way = (point[i-1].way+data[i]+4)%4;
        int x = point[i-1].x;
        int y = point[i-1].y;

        // 细节:找出现在的位置
        switch(point[i-1].way) {
            case R: y += 1; break;
            case L: y -= 1; break;
            case U: x -= 1; break;
            case D: break;
        }
        switch (way) {
            case R: y += 1; break;
            case L: y -= 1; break;
            case U: break;
            case D: x += 1; break;
        }

        point[i] = Point(x, y, way);

        //printf("%d,%d,%c\n",x,y,"RULD"[way]);

        umost = min(umost, x);
        dmost = max(dmost, x);

        lmost = min(lmost, y);
        rmost = max(rmost, y);
    }
    //printf("   %d \n%d   %d\n   %d\n", umost, lmost, rmost, dmost);
    memset(mat, ‘ ‘, sizeof(mat));
    for (int i = 0; i < end; i++) {
        mat[point[i].x-umost][point[i].y-lmost] = (point[i].way == L || point[i].way == R)?‘_‘:‘|‘;
    }
    dmost = dmost - umost;
    rmost = rmost - lmost;
    for (int i = 0; i <= dmost; i++) {
        mat[i][rmost+1] = 0;
        int p = rmost;
        while (mat[i][p] == ‘ ‘) mat[i][p--] = 0;
        printf("%s\n", mat[i]);
    }
    puts("^");
    //printf("   %d \n%d   %d\n   %d\n", umost, lmost, rmost, dmost);
}

int main() {
    int n;
    while (scanf("%d", &n) != EOF) {
        if (n == 0) break;
        pp = 0;
        paper[pp++] = Paper(0,1<<n,true);

        memset(data, -1, sizeof(data));
        for (int i = 0; i < n; i++) {
            int nowpp = pp;
            for (int j = 0; j < nowpp; j++) {
                flod(paper[j]);
            }
        }

        //for (int i = 1; i < (1<<n); i++) {
        //    printf("%c ", "^v"[data[i]==1]);
        //}puts("");

        showGraph(1<<n);
    }
    return 0;
}
时间: 2024-11-05 09:20:28

uva 177:Paper Folding(模拟 Grade D)的相关文章

177 - Paper Folding (找规律)

一开始看这题感觉无从下手,甚至一开始根本没理解题意 .后来明白了,是一张纸,每次都是从右向左折叠,注意折叠后不要动 . 折叠完n次后,最底下那一个纸条要保持原位置不动(水平放置),其他的按题目要求展开,从侧面就会看到一条连续的"美丽"曲线 . 那么怎么样找到这条曲线呢? 其实是有规律可循的 .我们把边看作路径,那么行走的方向命令就可以写出了 . 如下: n = 1 --> ru n = 2 --> rulu n = 3 --> rululdlu n = 4 -->

Uva - 1513 Moive collection ( 模拟栈 + 树状数组基本操作 )

Uva - 1513 Moive collection ( 模拟栈 + 树状数组基本操作 ) 题意: 一个书架,原来所有的书都是按顺序摆好的,书的编号从1开始到n 操作: 取出一本书,统计在这本书之前有多少本书,统计完之后,将这本书放在书架的第一位. 如:  1 2 3 4 5取4   4 1 2 3 5 (取之前,有3本书在4前面,取完后,将4放在栈顶)取4   4 1 2 3 5 (取之前,有0本书在4前面,取完后,将4放在栈顶)取2   2 4 1 3 5 (取之前,有2本书在2前面,取完

uva 1156 - Pixel Shuffle(模拟+置换)

题目链接:uva 1156 - Pixel Shuffle 题目大意:给定一个N*N的黑白位图,有7种操作,并且对应在指令后加上'-'即为操作的逆,给定N和一系列操作,(从最后一个开始执行),问说这一套指令需要执行多少次才能形成循环. 解题思路:模拟指令执行后获得一个置换,分解成若干的循环,各个循环长度的最小公倍数即使答案. #include <cstdio> #include <cstring> #include <algorithm> using namespace

UVA 1594:Ducci Sequence (模拟 Grade E)

题意: 对于一个n元组(a0,a1,...),一次变换后变成(|a0-a1|,|a1-a2|,...) 问1000次变换以内是否存在循环. 思路: 模拟,map判重 代码: #include <cstdio> #include <cstring> #include <map> #include <cmath> #include <algorithm> using namespace std; struct Node{ int a[16]; int

UVA 1593: Alignment of Code(模拟 Grade D)

题意: 格式化代码.每个单词对齐,至少隔开一个空格. 思路: 模拟.求出每个单词最大长度,然后按行输出. 代码: #include <cstdio> #include <cstdlib> #include <cstring> char words[1200][190][90]; int maxLen[190]; char tmp[200]; typedef char * pchar; int readStr(pchar &str, char *out) { in

UVA 1589:Xiangqi (模拟 Grade D)

题目: 象棋,黑棋只有将,红棋有帅车马炮.问是否死将. 思路: 对方将四个方向走一步,看看会不会被吃. 代码: 很难看……WA了很多发,还越界等等. #include <cstdio> #include <cstring> #include <cstdlib> char graph[13][13]; int go[4][2] = {{1,0},{0,1},{-1,0},{0,-1}}; bool inBlackPalace(int x, int y) { return

UVa 213 信息编码!模拟!

背景:一次ac!!而且调试时间也短!!!!看来这个自定义函数,确实是一个好的方法!!构思又清晰,调试又明朗! 思路:一些单一的函数堆砌而成,每个函数有自己的功能. 学习:1.我是采用模拟手算二进制为十进制的方法,而小紫书上给出的方法似乎更简单:(这似乎透露除了字符串数转化普通数的方法)(普通二进制数,转化为十进制数就一位一位的拆分) //assumpt that temp[] have n charnumbers int decimal=0; for(int i = 0;i < n;i++){

UVA 1368 DNA(模拟+贪心)

DNA (Deoxyribonucleic Acid) is the molecule which contains the genetic instructions. It consists of four different nucleotides, namely Adenine, Thymine, Guanine, and Cytosine as shown in Figure 1. If we represent a nucleotide by its initial character

UVA - 246 10-20-30 (模拟+STL)

Description  10-20-30  A simple solitaire card game called 10-20-30 uses a standard deck of 52 playing cards in which suit is irrelevant. The value of a face card (king, queen, jack) is 10. The value of an ace is one. The value of each of the other c