Uva 177 Paper Folding(模拟?Orz)

来源:互联网 发布:开票软件上有小盾牌 编辑:程序博客网 时间:2024/05/01 02:48

题意:一张纸(其实理解成一条线可能更好理解一点) 经过n次对折后, 会产生很多方向不同的折痕, 然后要输出按折痕打开后的形状。

一看到这道题的输出就傻了,,用‘|’和‘_'画图真是简直了。。然后仔细研究一会会发现,n每次加一就是将n - 1的图以最后一个点为基准顺时针旋转90度。然后模拟一下从起点开始画图的过程中每条边的走势,转弯方向,分析后会发现一共8中情况:上左, 上右, 右上, 右下, 下左, 下右, 左上, 左下。因此要记录每条边的走向, 由于每条边都是由之前存在的某条边旋转而来, 因此方向就可以推导出来,问题就解决了。

另外一个问题就是, 将n取不同值的图都存在一个数组中, 于是还要记录n取每个值的时候的上下左右边界, 以及这条边第一次出现的n的值, 不然会输出很奇怪的东西Orz。 

思路很丑代码也很丑, 看别人有dfs很短的解法, 很神奇,,还看到有人打表但是我尝试打表的时候发现代码太长了Orz。

#include <set>#include <map>#include <queue>#include <stack>#include <cmath>#include <string>#include <cctype>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <sstream>#include <iostream>#include <algorithm>using namespace std;#define ls id<<1,l,mid#define rs id<<1|1,mid+1,r#define OFF(x) memset(x,-1,sizeof x)#define CLR(x) memset(x,0,sizeof x)#define MEM(x) memset(x,0x3f,sizeof x)typedef long long ll ;typedef pair<int,int> pii ;const int maxn = 1e4+50 ;const int inf = 0x3f3f3f3f ;const int MOD = 1e9+7 ;const int N = 20;const int OF = 5000;const int Maxn = 1e3 ;struct edge{    int x,y,dir;} fold[10*maxn];char mp[maxn][maxn];int l[N],r[N][maxn],U[N],d[N],LV[maxn][maxn];void expand(int id,edge u) {    int x=u.x,y=u.y;    l[id]=min(l[id],y);    r[id][x]=max(r[id][x],y);    U[id]=min(U[id],x);    d[id]=max(d[id],x);}void add(int tme,int id) {    int x=fold[id].x,y=fold[id].y;    int dir=fold[id].dir;    edge u;    if (dir%4==1) {        u.x=x;        u.y=y+1;        if (dir>4) u.y-=2;        mp[u.x][u.y]='|';    } else if (dir%4==2) {        u.y=y+1;        u.x=x;        if (dir>4) u.x--;        mp[u.x][u.y]='_';    } else if (dir%4==3) {        u.x=x+1;        u.y=y-1;        if (dir>4) u.y+=2;        mp[u.x][u.y]='|';    } else {        u.x=x;        if (dir<=4) u.x--;        u.y=y-1;        mp[u.x][u.y]='_';    }    LV[u.x][u.y]=tme;    x=u.x;y=u.y;    l[tme]=min(l[tme],y);    r[tme][x]=max(r[tme][x],y);    U[tme]=min(U[tme],x);    d[tme]=max(d[tme],x);    fold[id+1].x=u.x;    fold[id+1].y=u.y;//    memcpy(&fold[id+1],&u,sizeof(u));}void getdir(int tme,int v) {    int u=(1<<tme)-v;    int dir=fold[u].dir;    edge &t=fold[v];    if (dir<=4) t.dir=4+dir;    else if (dir==5) t.dir=3;    else if (dir==6) t.dir=4;    else if (dir==7) t.dir=1;    else t.dir=2;}int main () {#ifdef LOCALfreopen("C:\\Users\\Administrator\\Desktop\\in.txt","r",stdin);    freopen("C:\\Users\\Administrator\\Desktop\\out.txt","w",stdout);#endif    MEM(l);CLR(mp);    MEM(U);CLR(LV);    CLR(r);CLR(d);    mp[OF][OF]='_';    mp[OF][OF+1]='|';    fold[1].dir=1;fold[2].dir=4;    fold[1].x=fold[1].y=fold[2].x=OF;    fold[2].y=OF+1;    l[1]=OF,r[1][OF]=OF+1;    U[1]=OF;d[1]=OF;//    for (int i=1;i<=(1<<14);i++) fold[i].dir=1;    for (int i=2;i<=14;i++) {        int dis=1<<(i-1);        for (int j=1;j<=dis;j++) {            add(i,dis+j-1);            if (j<dis) getdir(i,dis+j);            else fold[j+dis].dir=4;        }    }    for (int i=1;i<=14;i++) {        U[i]=min(U[i],U[i-1]);        d[i]=max(d[i],d[i-1]);        l[i]=min(l[i],l[i-1]);        for (int j=U[i];j<=d[i];j++) r[i][j]=max(r[i][j],r[i-1][j]);    }    int n;    while (scanf("%d",&n)&&n) {        if (n==1) printf("_|\n^\n") ;        else {            for (int i=U[n];i<=d[n];i++) {                for (int j=l[n];j<=r[n][i];j++) {                    if (mp[i][j]==0||LV[i][j]>n) printf(" ");                    else printf("%c",mp[i][j]);                }                puts("");            }            puts("^"); ;        }    }return 0;}


0 0
原创粉丝点击