题目
你喜欢折纸吗?给你一张很大的纸,对折以后再对折,再对折……每次对折都是从右往左折,因此在折了很多次以后,原先的大纸会变成一个窄窄的纸条。现在把这个纸条沿着折纸的痕迹打开,每次都只打开“一半”,即把每个折痕做成一个直角,那么从纸的一端沿着和纸面平行的方向看过去,会看到一个美妙的曲线。
例如,如果对折了4次,那么打开以后将看到如图所示的曲线。注意,该曲线是不自交的,虽然有两个转折点重合。给出对折的次数,请编程绘出打开后生成的曲线。
样例输入
2 4 1 0
样例输出
|_ _| ^ _ _ |_|_| |_ _| _| |_| ^ _| ^
题解
啊!又是大模拟
具体细节最好还是自己考虑下,看了下面的内容再做这题就没意思了。只需要2小时就能做出来的……
首先折纸的过程要仔细考虑……
对折一次可以看成3步
那么就可以得到下面这种图
可以把整张纸看成一堆线段……
从下向上编号,在右端向上走的是左转,右端向下走的是右转,剩下的情况看图吧……
左面和右边变化的数字很容易就可以找出规律……
可以根据此计算输出的所有线段的位置,为了记录这个位置我们用一个vector保存……因为坐标可能为负,因此数组不好保存。
最后把vector转换为数组,最后输出,还要注意行尾不能有空格
转换的时候依照这个:
0 1 2 3 4 5 6 7 8 9 a b c 0. _ _ _ _ _ _ _ _ _ _ _ _ 1.|_|_|_|_|_|_|_|_|_|_|_|_| 2.|_|_|_|_|_|_|_|_|_|_|_|_| 3.|_|_|_|_|_|_|_|_|_|_|_|_| 4.|_|_|_|_|_|_|_|_|_|_|_|_| 5.|_|_|_|_|_|_|_|_|_|_|_|_|
剩下的就非常容易了……
AC代码
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math") #include<bits/stdc++.h> using namespace std; #define REP(r,x,y) for(register int r=(x); r<(y); r++) #define REPE(r,x,y) for(register int r=(x); r<=(y); r++) #ifdef sahdsg #define DBG(...) printf(__VA_ARGS__) #else #define DBG(...) #endif #define MAXN 207 #define MAXX 8193 char str[MAXN]; struct _xian{ int dd[2]; }xian[MAXX]; int n; int cnt; inline void build() { xian[0].dd[0]=xian[1].dd[1]=0; int pos=2; REP(i,1,n) { int st=(1<<i)-1; for(register int j=st; j>=-st; j-=2) { xian[pos++].dd[0]=j; } } int st=cnt-1; pos=0; for(register int j=st; j>=-st; j-=2) { xian[pos++].dd[1]=j; } } const char way[] = "RDLU"; //shun const int dx[]={1, 0,-1, 0}; const int dy[]={0,-1, 0, 1}; struct _line{ int x,y; bool vertical; }; vector<_line> vt; bool hen[MAXN][MAXN]; bool shu[MAXN][MAXN]; int maxl[MAXN]; int main() { #ifdef sahdsg // freopen("in.txt", "r", stdin); #endif while(~scanf("%d", &n) && n) { if(n==1) { puts("_| ^"); continue; } vt.clear(); cnt=1<<n; build(); #define l 0 #define r 1 int now=0, pos=r, fx=0; int x=1,y=0; while(xian[now].dd[pos]) { vt.push_back((_line){x-(dx[fx]>0),y+(dy[fx]<0),(now&1)==1}); bool a=xian[now].dd[pos]>0; bool b=pos; int go=(a==b)*2-1; //L:-1 R:1 fx+=go; if(fx<0) fx=3; if(fx>3) fx=0; x+=dx[fx], y+=dy[fx]; now += xian[now].dd[pos]; pos=!pos; } vt.push_back((_line){x-(dx[fx]>0),y+(dy[fx]<0),(now&1)==1}); int minx=0, miny=0, maxx=0, maxy=0; REP(i,0,vt.size()) { minx=min(minx,vt[i].x); maxx=max(maxx,vt[i].x); miny=min(miny,vt[i].y); maxy=max(maxy,vt[i].y); } memset(hen,0,sizeof hen); memset(shu,0,sizeof shu); memset(maxl,-1,sizeof maxl); REP(i,0,vt.size()) { int x=vt[i].x-minx; int y=vt[i].y-miny; maxl[y]=max(maxl[y],x); if(vt[i].vertical) { shu[x][y]=1; } else { hen[x][y]=1; } } REPE(i,0,maxy-miny) { REPE(j,0,maxl[i]) { putchar(shu[j][i]?'|':' '); if(hen[j][i]) putchar('_'); else if(j<maxl[i]) putchar(' '); } putchar(' '); } putchar('^');putchar(' '); #undef l #undef r } return 0; }