本题是著名的折纸痕问题。。本是练习递归,但是我觉得模拟的成分更大。暂把它归为模拟题。
Url:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=113
XXX 说,模拟题是最简单的,我觉得模拟题其实是最难做的。
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using namespace std;
#define Max 15
int turn[1<<Max];//折痕的方向,0代表顺时针,1代表逆时针
int x[Max],y[Max];//每个示例对应的"S"的坐标
int w[Max],h[Max];//每个示例对应的宽度和高度
char map[Max][150][250];//第二维和第三维最大值可以有getPos()函数计算,k = 13即可
int width[Max][150];//由于有些忽略空格,width必须计算
void getTurn(int l,int r,int x,int dir)
{
turn[x] = dir;
if(l == r)
{
return;
}
getTurn(l,x-1,(x-1+l)>>1,0);
getTurn(x+1,r,(r+x+1)>>1,1);
}
void getPos(int &x,int &y,int &w,int &h,int n)
{
int dir = 0;
int xx = 0,yy = 0;
int pos_x = 0,pos_y = 0;
int nec_x = 0,nec_y = 0;
for(int i=0; i<n; i++)
{
//顺时针
if(turn[i] == 0)
{
if(dir == 0)
{
yy++;
}
else if(dir == 1)
{
xx--;
yy--;
}
else if(dir == 2)
{
xx++;
yy--;
}
else if(dir == 3)
{
yy++;
}
dir = (dir + 1)%4;
}
//逆时针
else if(turn[i] == 1)
{
if(dir == 0)
{
xx++;
yy++;
}
else if(dir == 1)
{
xx--;
yy++;
}
else if(dir == 2)
{
yy--;
}
else if(dir == 3)
{
yy--;
}
dir = (dir - 1 + 4)%4;
}
if(xx>=0)
{
pos_x = max(pos_x,xx);
}
else
{
nec_x = min(nec_x,xx);
}
if(yy>=0)
{
pos_y = max(pos_y,yy);
}
else
{
nec_y = min(nec_y,yy);
}
}
w = pos_y - nec_y + 1;
h = pos_x - nec_x + 1;
x = -nec_x;
y = -nec_y;
//printf("w = %d,h = %d,x = %d,y = %d\n",w,h,x,y);
}
void getFill(int k,int x,int y,int n)
{
int xx = x,yy = y;
int dir = 0;
map[k][xx][yy] = '_';
width[k][xx]=max(width[k][xx],yy);
for(int i=0; i<n; i++)
{
//顺时针
if(turn[i] == 0)
{
if(dir == 0)
{
yy++;
map[k][xx][yy] = '|';
}
else if(dir == 1)
{
xx--;
yy--;
map[k][xx][yy] = '_';
}
else if(dir == 2)
{
xx++;
yy--;
map[k][xx][yy] = '|';
}
else if(dir == 3)
{
yy++;
map[k][xx][yy] = '_';
}
dir = (dir + 1)%4;
}
//逆时针
else if(turn[i] == 1)
{
if(dir == 0)
{
xx++;
yy++;
map[k][xx][yy] = '|';
}
else if(dir == 1)
{
xx--;
yy++;
map[k][xx][yy] = '_';
}
else if(dir == 2)
{
yy--;
map[k][xx][yy] = '|';
}
else if(dir == 3)
{
yy--;
map[k][xx][yy] = '_';
}
dir = (dir - 1 + 4)%4;
}
width[k][xx]=max(width[k][xx],yy);
}
}
void getPrint(int k)
{
for(int i=0;i<h[k];i++)
{
for(int j=0;j<=width[k][i];j++)
{
if(map[k][i][j] == 0)
{
printf(" ");
}
else
{
printf("%c",map[k][i][j]);
}
}
printf("\n");
}
printf("^\n");
}
void solve(int k)
{
int n = (1<<k) - 1;//折痕的数目
getTurn(0,n-1,(n-1)>>1,0);
getPos(x[k],y[k],w[k],h[k],n);
getFill(k,x[k],y[k],n);
getPrint(k);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int k;
memset(map,0,sizeof(map));
while(true)
{
scanf("%d",&k);
if(k == 0)
{
break;
}
solve(k);
}
return 0;
}