这道题一看就知道要用递归,我想不通的是怎么保存状态,最后用了结构体,保存了没条线的位置和方向,然后定义一下两条线之间方向转化时对应的坐标变化,应当是最暴力的一种方法,还好题目规模不大,一次就ac了。
觉得保存之后,对结构体数组排序这点想的不错,结合全局变量min_x, 一下就把显示的问题解决了,开心。
这道题如果改进的话,应该是对状态的定义和保存上,对称性我用的还是不够充分。
#include <cstdio>
#include <cstdlib>
#include <cmath>
using namespace std;
const int MAX = 100000;
const int RIGHT = 0, DOWN = 1, LEFT = 2, UP = 3;
struct line{
int x;
int y;
int d;
};
line l[MAX];
int cu, min_x, max_x;
void ad_cordi(int i, int j, int &c_x, int &c_y){
if(i == RIGHT || j == RIGHT)
c_x++;
else if(i == LEFT || j == LEFT)
c_x--;
if(j == UP)
c_y--;
else if(i == DOWN)
c_y++;
}
void fold(int n){
if(n == 0){
l[cu].x = l[cu].y = l[cu].d = 0;
min_x = 0;max_x = 0;
return;
}
fold(n-1);
int c_x = l[cu].x, c_y = l[cu].y;
for(int i=cu;i>=0;i--){
l[++cu].d = (l[i].d + 1)%4;
ad_cordi(l[cu-1].d, l[cu].d, c_x, c_y);
l[cu].x = c_x;
l[cu].y = c_y;
if(c_x < min_x)
min_x = c_x;
if(c_x > max_x)
max_x = c_x;
}
}
int compare(const void* a, const void* b)
{
struct line *a1 = (struct line *) a;
struct line *a2 = (struct line *) b;
if(a1->y != a2->y)
return (a2->y - a1->y);
else
return (a1->x - a2->x);
}
int main(){
int n;
while(~scanf("%d", &n)&&n){
cu = 0;
fold(n);
qsort(l, pow(2, n), sizeof(l[0]), compare);
int ptr = min_x, py = l[0].y;
for(int i=0;i<pow(2, n);i++){
if(py != l[i].y){
py = l[i].y;
printf("\n");
ptr = min_x;
}
while(ptr < l[i].x)
{printf(" ");ptr++;}
if(l[i].d%2 == 0)
printf("_");
else
printf("|");
ptr++;
}
printf("\n^\n");
}
return 0;
}