P.S.模拟真の难打,我花了近乎三小时!o(≧口≦)o 模拟题真的要思路清晰!分块调试。
题意:著名的折纸问题:给你一张很大的纸,对折以后再对折,再对折……每次对折都是从右往左折,因此在折了很多次以后,原先的大纸会变成一个窄窄的纸条。现在把这个纸条沿着折纸的痕迹打开,每次都只打开“一半”,即把每个痕迹做成一个直角,那么从纸的一端沿着和纸面平行的方向看过去,会看到一条美妙的曲线。输入对折次数,请绘出打开后生成的曲线。(P.S.看到画图我就笑了......<( - ︿-)>)
解法:模拟。1.先找到变化规律给每一“笔”编号(这个需要前一笔的方向和现在这一笔的方向共同确定位置,由于用 _ 和 | 输出会有偏差的......);2.再定一个原点,把负数的横、纵坐标的点全部“移”到非负整数处,记下坐标,这样才能输出好;3.依行、列输出。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<algorithm> 5 #include<iostream> 6 using namespace std; 7 8 const int N=15,NN=13; 9 struct node {int x[1<<N],y[1<<N],s[1<<N];} a[N]; 10 struct hp {int x,y,p;} b[N][1<<N]; 11 int dir[4][2]={{0,1},{-1,0},{0,-1},{0,0}};//前一个到现在 向右、上、左、下 12 int dirr[4][2]={{0,1},{0,0},{0,-1},{1,0}};//对现在的再调整 13 char str[2]={'_','|'}; 14 15 int mmin(int x,int y) {return x<y?x:y;} 16 int mmax(int x,int y) {return x>y?x:y;} 17 bool cmp(hp x,hp y) 18 { 19 if (x.x!=y.x) return x.x<y.x; 20 return x.y<y.y; 21 } 22 void init() 23 { 24 a[0].s[1]=b[0][1].p=0; 25 a[0].x[1]=a[0].y[1]=b[0][1].x=b[0][1].y=0;//原点 26 for (int i=1;i<=NN;i++) 27 { 28 int tt=1<<(i-1),t=1<<i; 29 int mnx=0,mny=0;//最左上端的点离起点的行、列距离 30 a[i].x[0]=a[i].y[0]=0;//源点 31 for (int j=1;j<=t;j++) 32 { 33 if (j<=tt) 34 { 35 a[i].s[j]=a[i-1].s[j];//前一半部分一样 36 a[i].x[j]=a[i-1].x[j]; 37 a[i].y[j]=a[i-1].y[j]; 38 } 39 else 40 { 41 int p,q; 42 p=(a[i].s[tt-(j-tt)+1]+1)%4,q=a[i].s[j-1]; 43 a[i].s[j]=p; 44 a[i].x[j]=a[i].x[j-1]+dirr[p][0]+dir[q][0];//j-1 45 a[i].y[j]=a[i].y[j-1]+dirr[p][1]+dir[q][1];//需要前一个和现在这个配合才行 46 } 47 mnx=mmin(mnx,a[i].x[j]),mny=mmin(mny,a[i].y[j]);//一般为负数 48 } 49 for (int j=1;j<=t;j++)//调整坐标 50 { 51 a[i].x[j]-=mnx,a[i].y[j]-=mny; 52 b[i][j].x=a[i].x[j],b[i][j].y=a[i].y[j]; 53 b[i][j].p=a[i].s[j]&1; 54 } 55 sort(b[i]+1,b[i]+1+t,cmp);//为了输出 56 b[i][0].x=b[i][0].y=-1; 57 } 58 } 59 void print(int i) 60 { 61 int x=0,y=0,t=1<<i; 62 for (int j=1;j<=t;j++) 63 { 64 if (b[i][j].x!=b[i][j-1].x) 65 { 66 while (x<b[i][j].x) x++,printf(" "); 67 y=0; 68 } 69 while (y<b[i][j].y) y++,printf(" "); 70 y++,printf("%c",str[b[i][j].p]); 71 } 72 printf(" ^ "); 73 } 74 int main() 75 { 76 init(); 77 while (1) 78 { 79 int n; 80 scanf("%d",&n); 81 if (!n) break; 82 print(n); 83 } 84 return 0; 85 }