1. 程式人生 > >UVA 177 Paper Folding

UVA 177 Paper Folding

img tor 規律 具體細節 tin alt image false rdquo

題目

你喜歡折紙嗎?給你一張很大的紙,對折以後再對折,再對折……每次對折都是從右往左折,因此在折了很多次以後,原先的大紙會變成一個窄窄的紙條。現在把這個紙條沿著折紙的痕跡打開,每次都只打開“一半”,即把每個折痕做成一個直角,那麽從紙的一端沿著和紙面平行的方向看過去,會看到一個美妙的曲線。

技術分享圖片

例如,如果對折了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("_|\n^");
			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(‘\n‘);
		}
		putchar(‘^‘);putchar(‘\n‘);
		#undef l
		#undef r
	}
	return 0;
}

UVA 177 Paper Folding