zoukankan      html  css  js  c++  java
  • UVA 177 Paper Folding

    题目

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

    例如,如果对折了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;
    }
    
  • 相关阅读:
    【HDOJ】1058 Humble Numbers
    activity去标题栏操作&保留高版本主题
    谷歌安卓官方开发者网站 https://developer.android.google.cn
    TortoiseGIT
    Git的优势
    eoe开发社区
    安卓巴士 http://www.apkbus.com/
    Git简介
    SVN标准目录结构
    关于人生的
  • 原文地址:https://www.cnblogs.com/sahdsg/p/10502272.html
Copyright © 2011-2022 走看看