"The instructions to turn always to the left reminded me that such was the common procedure for discovering the central courtyard of certain labyrinths."
in The garden of forking paths by Jorge Luis Borges
A fellow librarian has exhumed in the Library of Babel a vast catalogue of labyrinths. It is our duty to classify them all and we count on your assistance. The plans of the labyrinths are already digitized and we need you to write a program to decide if the central courtyard of a given labyrinth can be reached following the simple procedure of always turning left at any intersection, and thus be called a left labyrinth.
The digitalization process reduces the plan of a labyrinth to a grid of cells, being each cell either a block of wall or just flooor. Walls are sequences of contiguous blocks, forming either horizontal or vertical corridors between them. Each labyrinth has a single entrance, a hole in its exterior walls, and a single central courtyard. The courtyard differs from the corridors in the shape: a floor cell in a corridor has at least 2 block of wall on each side. You can assume that each plan has a single labyrinth and its outside walls can be contoured within the plan.
Input
The first two input lines are the integers, smaller than 100,
n – the number of lines in the map, and
m – the number of characters per line in the map.
The following n lines, each with m characters, have only two valid character values:
# – (sharp) representing a block of wall;
. – (point) representing part of the floor.
Process to the end of file.
Output
Your program must write either YES if the given labyrinth is a left labyrinth or NO otherwise.
Sample Input
30
50
…………………………………………..
…………………………………………..
…………………………………………..
…..##############…………..############…..
…..#………#..#…………..#……….#…..
…..#.#######.#.##…………..#.########.#…..
…..#.#…..#….#…………..#.#……#.#…..
…..#.#.#####.####…………..#.#.####.#.#…..
…..#.#…..#…#################.#.##.#…#…..
…..#.#####.###……………………#.#.#…..
…..#………#.###############.#.##########…..
…..#########.#.#.#………..#.#..#………….
………….#.#.#.#………..###.##………….
………….#.#.#.#………..#….#………….
………….#.#…#………..#.##.#………….
………….#######………..#.##.#………….
………….#……………..#.#..#………….
………….#.#################.####………….
…..#########…#……………..##########…..
…..#………###.#.#.##########.#######.#.#…..
…..#.#########…..#.#……….#…..#.#.#…..
…..#.#………#####.##########.#.###.#.#.#…..
…..#.######.#####………..#.#.#.#.#.#.#.#…..
…..#……#…..#………..#…..#.#.#.#.#…..
…..#.##########.#………..#####.#.#.#.#.#…..
…..#…………#………..#………..#.#…..
…..##############………..###############…..
…………………………………………..
…………………………………………..
…………………………………………..
Sample Output
YES
开始只是过了zoj,poj怎么也过不了,数据更加强一点,发现出问题出在找起点。
想到一个好的方法。
我把整个char数组都置为'.',数据放在1-n和1-m,每次找起点从0,0这个不存在的点进行搜索,这样就可以方便找到起点了。
还有一种数据不能过,但是幸好两个oj都没有这么变态的数据
4 4
..##
#..#
#..#
####
# include <iostream>
# include <cstring>
# include <stdio.h>
using namespace std;
char mg[120][120];
int n,m;
int tx,ty,sx,sy;
int dx[] = {-1,0,1,0};
int dy[] = {0,1,0,-1};
bool dir[120][120][4];
bool vis[120][120];
bool ans;
struct point{
int x,y;
};
point pp[10000];
bool isok(int x,int y){
if(x>=0&&x<=n+1&&y>=0&&y<=m+1) return true;
else return false;
}
bool isok2(int x,int y){
if(x>=1&&x<=n&&y>=1&&y<=m) return true;
else return false;
}
bool istrue(int x,int y){
if(isok2(x+1,y+1)&&mg[x+1][y]=='.'&&mg[x+1][y+1]=='.'&&mg[x][y+1]=='.') return true;
if(isok2(x-1,y-1)&&mg[x-1][y]=='.'&&mg[x-1][y-1]=='.'&&mg[x][y-1]=='.') return true;
if(isok2(x-1,y+1)&&mg[x-1][y]=='.'&&mg[x-1][y+1]=='.'&&mg[x][y+1]=='.') return true;
if(isok2(x+1,y-1)&&mg[x][y-1]=='.'&&mg[x+1][y-1]=='.'&&mg[x+1][y]=='.') return true;
return false;
}
void bfs(){
int front = 0,rear = 0;
point st;
st.x = 0,st.y = 0;
vis[0][0] = true;
mg[st.x][st.y] = '*';
pp[rear++] = st;
point tp;
while(front<rear){
tp = pp[front++];
if((mg[tp.x-1][tp.y]=='#'&&mg[tp.x+1][tp.y]=='#')||(mg[tp.x][tp.y-1]=='#'&&mg[tp.x][tp.y+1]=='#')){
sx = tp.x;sy = tp.y;
return ;
}
mg[tp.x][tp.y] = '*';
for(int i=0;i<4;++i){
int xx = tp.x+dx[i];
int yy = tp.y+dy[i];
if(isok(xx,yy)){
if(!vis[xx][yy]&&mg[xx][yy] == '.'){
point temp;
temp.x = xx;temp.y = yy;
vis[xx][yy] = true;
pp[rear++] = temp;
}
}
}
}
}
void dfs(int x,int y,int d){
//printf("%d %d\n",x,y);
if(ans == true) return ;
//dir[x][y][d] = true;
if(istrue(x,y)){
ans = true;
}
else{
//printf("11111\n");
for(int i=3;i<=6;++i){
int td = (d+i)%4;
//printf("%d\n",td);
if(isok2(x+dx[td],y+dy[td])&&dir[x][y][td] == false&&mg[x+dx[td]][y+dy[td]]=='.'){
dir[x][y][td] = true;
dfs(x+dx[td],y+dy[td],td);
break;
}
}
}
}
int main()
{
//freopen("1.txt","r",stdin);
while(scanf("%d%d",&n,&m)!=EOF){
memset(vis,false,sizeof(vis));
memset(mg,'.',sizeof(mg));
//sx = 1,sy = 1;
getchar();
for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
scanf("%c",&mg[i][j]);
}
getchar();
}
bfs();
//printf("%d %d\n",sx,sy);
for(int i=0;i<=n;++i){
for(int j=0;j<=m;++j){
if(mg[i][j] == '*') mg[i][j] = '#';
}
}
/*for(int i=1;i<=n;++i){
for(int j=1;j<=m;++j){
printf("%c",mg[i][j]);
}
printf("\n");
}*/
memset(dir,false,sizeof(dir));
ans = false;
dfs(sx,sy,0);
if(ans) printf("YES\n");
else printf("NO\n");
}
return 0;
}
本文深入探讨了Jorge Luis Borges的《分岔路径花园》中关于左转迷宫的概念,并通过算法实现来判断一个迷宫是否可以遵循左转规则到达中央庭院。文章详细介绍了迷宫地图的数字化过程,以及如何编写程序来识别满足特定条件的左转迷宫。通过实例输入输出,阐述了解决方案的步骤和关键逻辑。

被折叠的 条评论
为什么被折叠?



