题目描述:
给你一个N*N方格的迷宫,迷宫中有若干障碍,障碍处不可通过。每一步你只能向上、向下、向左、向右走一格,且不能走出迷宫。迷宫的四个角是:左上角:(1,1),右上角:(1,n),左下角:(n,1),右下角:(n,n)。假设你在点(1,1)处,请你设计程序求解是否可以到达(n,n)处。保证起点(1,1)和终点(n,n)可以通行。
输入数据第一行给一个整数n。数据给出一个n*n的字符矩阵,’*’代表此处可以通行,’#’代表此处不可以通行。
你需要输出”YES”(表示可以通行),”NO”(表示不能通行)。注:不输出引号,注意大小写。
输入
第一行一个n ,(n<=200);
其后一个n*n的字符矩阵,意义见题面。
输出
“YES”或者“NO”。分别表示能到达和不能到达。
样例输入
3
***
*##
***
样例输出
YES
链接http://222.22.65.164/problem.php?id=4223
思路:
0.首先把输入数据用二维数组储存这个迷宫图,0表示可以走,非零表示不可以走,1为墙,大于一为当前走的第n-1步,另外在输入shi记时加上围墙,不然数组会越界;
1.一共有四个方向:上下左右,用一个方向函数next()实现;
void next(int a)
{
switch(a)
{
case 1:pp.y++;break;//向右
case 2:pp.x++;break;//向下
case 3:pp.y--;break;//向左
case 4:pp.x--;//向上
}
}
2.用一个结构体表示当前走的位置:
struct PP{
int x,y,p,n;
}
其中x,y为当前坐标,p表示要走的方向,n表示当前走的第n步;
3.用一个栈储走的每一步的状态;
struct PP{
int x,y,p,n;
}pp,stack[10000];//用数组实现栈
typedef struct QQ{
pp *base;
pp *top;
int size;
}sqstack;//用链表实现栈
代码分别如下:
数组保存栈:
#include<stdio.h>
struct PP{
int x,y,p,n;
}pp,stack[10000];
int top=0,n;
void next(int a)
{
switch(a)
{
case 1:pp.y++;break;//向右
case 2:pp.x++;break;//向下
case 3:pp.y--;break;//向左
case 4:pp.x--;//向上
}
}
int main()
{
scanf("%d",&n);
getchar();
int map[203][203];
char c;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
c=getchar();
while(c!='#'&&c!='*')//这个一定要加,我这个一改就ac了,防止输入换行的时候出问题
c=getchar();
map[i][j]=(c=='#'?1:0);
}
getchar();
}
for(int i=0;i<=n+1;i++)//加围墙
{
map[0][i]=1;
map[n+1][i]=1;
map[i][0]=1;
map[i][n+1]=1;
}
pp.x=1;
pp.y=1;
pp.p=1;
pp.n=1;
do
{
if(map[pp.x][pp.y]==0)
{
map[pp.x][pp.y]=++pp.n;
stack[top++]=pp;
if(pp.x==n&&pp.y==n)
break;
else
{
pp.p=1;
stack[top-1]=pp;
next(pp.p);
}
}
else
{
if(top)
{
pp=stack[top-1];
while(pp.p==4&&top)
{
map[pp.x][pp.y]=0;
pp.n--;
top--;
pp=stack[top-1];
}
if(pp.p<4)
{
pp.p++;
stack[top-1]=pp;
next(pp.p);
}
}
}
}while(top);
if(top)
printf("YES");
else
printf("NO");
return 0;
}
链表保存栈:
#include<stdio.h>
#include<stdlib.h>
#define ENF 100
#define END 10
#define OVERFLOW 0
#define ERROR 0
#define OK 1
typedef struct PP{
int x,y,p,n;
}pp;
typedef struct QQ{
pp *base;
pp *top;
int size;
}sqstack;
int initstack(sqstack &s)
{
s.base=(pp *)malloc(ENF*sizeof(pp));
if(!s.base)exit(OVERFLOW);
s.top=s.base;
s.size=ENF;
return OK;
}
int gettop(sqstack s,pp &e)
{
if(s.base==s.top)
return ERROR;
e=*(s.top-1);
return OK;
}
int push(sqstack &s,pp e)
{
if(s.top-s.base>=s.size)
{
s.base=(pp *)realloc(s.base,(s.size+END)*sizeof(pp));
if(!s.base)
exit(OVERFLOW);
s.top=s.base+s.size;
s.size+=END;
}
* s.top++=e;
return OK;
}
int pop(sqstack &s,pp &e)
{
if(s.top==s.base)
return ERROR;
e=*--s.top;
return OK;
}
int stackempty(sqstack s)
{
if(s.top==s.base)
return 1;
return 0;
}
int main()
{
int n;
scanf("%d",&n);
char temp;
getchar();
int map[203][203];
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
temp=getchar();
while(temp!='*'&&temp!='#')
temp=getchar();
if(temp=='*')
map[i][j]=0;
else
map[i][j]=1;
}
}
for(int i=0;i<=n+1;i++)
{
map[0][i]=1;
map[n+1][i]=1;
map[i][0]=1;
map[i][n+1]=1;
}
pp q;
q.x=1;
q.y=1;
q.p=1;
q.n=1;
sqstack stac;
initstack(stac);
do
{
if(map[q.x][q.y]==0)
{
map[q.x][q.y]=++q.n;
push(stac,q);
if(q.x==n&&q.y==n)
break;
else
{
q.p=1;
pp z;
pop(stac,z);
push(stac,q);
switch(q.p)
{
case 1:q.y++;break;
case 2:q.x++;break;
case 3:q.y--;break;
case 4:q.x--;
}
}
}
else
{
if(!stackempty(stac))
{
gettop(stac,q);
while(q.p==4&&(!stackempty(stac)))
{
map[q.x][q.y]=0;
q.n--;
pop(stac,q);
gettop(stac,q);
}
if(q.p<4)
{
q.p++;
pp z;
pop(stac,z);
push(stac,q);
switch(q.p)
{
case 1:q.y++;break;
case 2:q.x++;break;
case 3:q.y--;break;
case 4:q.x--;
}
}
}
}
}while(!stackempty(stac));
if(!stackempty(stac))
printf("YES");
else
printf("NO");
return 0;
}
提示:
此题数据尽量用%s读取,或采用
temp=getchar();
while(temp!='*'&&temp!='#') temp=getchar();
避免Windows和Linux环境造成的回车符不同问题,这个一定要注意,很重要!!!!!我改了好几天发现这个错误,真的是难找啊!醉了,卡了好几天,终于找到了,啊哈哈哈哈
2. 对于文件里的换行,
(1)Windows系统里,文件每行结尾是"<回车><换行>""\r\n"
(2)Mac系统里, 文件每行结尾是"<回车>",即'\r'
(3)Unix系统里, 文件每行结尾是"<换行>",即'\n'
详情见链接https://blog.csdn.net/loveprogram_1/article/details/48273747?utm_source=blogxgwz2