题意:
给定一个m × n (m行,n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去。令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的。我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一次转弯。gloria能从一个位置走到另外一个位置吗?
这题用普通的方法 不是超时 , 就是wa 。
老子我提交了50+
这题的数据确实是很牛逼啊 , 决对是设计出来的
到现在我还不知道我那个方法 , 为什么会wa
网上解题报告的解法:
这题用bfs来做 , 关键在于以一个什么方法来标记已经走过的点 , 这个地方 , 就是这个题目的关键 , 把这个问题解决了 ,这个题目也就A了
网上是这样做得 , 每次走的时候 , 都把这一方向的所以点走遍 , 然后把走过的点都标记 ,这样就能保证第一次走过这个点的时候的转弯次数一定是最少的。
代码:
#include
#include
#include
#include
using namespace std;
#define maxn 1100
char grap[maxn][maxn] ;
int pre[maxn][maxn];
int n , m;
int d_x[4] = {-1 , 1, 0 , 0};
int d_y[4] = {0 , 0 , -1 , 1};
int g , h , k ;
int sum , cf;
typedef struct xyy
{
int x ,y;
intsum;
int f;
}edge;
void init()
{
int i ,j;
memset(pre ,0 , sizeof(pre));
for(i = 0; i<= m+1 ; i++)
grap[0][i] =grap[n+1][i] = '*';
for(i = 0; i<= n+1 ; i++)
grap[i][0] =grap[i][m+1] = '*';
sum =0;
cf =-1;
}
void bfs(int x , int y)
{
queueq;
edge xy;
xy.x = x ,xy.y = y , xy.sum = 0 , xy.f = -1;
q.push(xy);
pre[x][y] =1;
int i;
while(!q.empty())
{
edge gh = q.front() , cf;
q.pop();
int x , y;
for(i = 0; i < 4; i++)
{
x =gh.x+d_x[i];
y = gh.y+d_y[i];
cf.sum =gh.sum;
cf.f =i;
if(gh.f !=-1 && gh.f != i)
{
cf.sum =gh.sum + 1;
}
if(cf.sum> k)
continue ;
while(grap[x][y] != '*')
{
if(pre[x][y]== 0)
{
cf.x =x;
cf.y =y;
if(cf.x == g&& cf.y == h && cf.sum <= k)
{
printf("yes\n");
return;
}
q.push(cf);
pre[x][y] =1;
}
x +=d_x[i];
y +=d_y[i];
}
}
}
printf("no\n");
}
int main()
{
int t;
scanf("%d" ,&t);
while(t--)
{
scanf("%d %d" , &n , &m);
init();
charch;
int i , x , y , j;
for( i=1;i<=n;i++)
{
getchar();
for( j=1;j<=m;j++)
{
scanf("%c",&ch);
grap[i][j]=ch;
}
//getchar();
}
scanf("%d %d %d %d %d" , &k , &y , &x , &h ,&g);
if(x==g&& y==h) printf("yes\n");
else bfs(x , y);
}
return0;
}
下面是我自己的方法 , 一直wa , 一直不知道是哪错了
定义了一个数组pre , 来标记到达每个点的最小转弯次数 , 同时判断这个点能不能入队列(能不能继续往下走) ,只有这点的转弯次数会小于等于 , 当前这个点的最小转弯次数时 , 才能入队列
pre[xx][yy] < cf.sum
这里有一个bug , 假如当前这个点的最小转弯次数为x , 而现在你有到达这个点 , 且这个点的转弯次数也是x , 此时 ,这个点也要入队列 , 因为从这个点到目标点 , 可能还要再转弯一次 。
代码:
#include
#include
#include
#include
using namespace std;
#define maxn 1100
char grap[maxn][maxn] ;
int pre[maxn][maxn];
int n , m;
int d_x[4] = {-1 , 1, 0 , 0};
int d_y[4] = {0 , 0 , -1 , 1};
int g , h , k ;
typedef struct xyy
{
int x ,y;
intsum;
int f;
}edge;
void init()
{
//
memset(pre, 0 , sizeof(pre));
int i ,j;
for(i = 0; i<= m+1 ; i++)
grap[0][i] =grap[n+1][i] = '*';
for(i = 0; i<= n+1 ; i++)
grap[i][0] =grap[i][m+1] = '*';
for(i = 1; i<= n; i++)
for(j = 1; j<= m; j++)
pre[i][j] =120;
}
void bfs(int x , int y)
{
queueq;
edge xy ,cf;
xy.x = x ,xy.y = y , xy.sum = 0 , xy.f = -1;
q.push(xy);
pre[x][y] =0;
int i , xx ,yy;
while(!q.empty())
{
edge gh =q.front() ;
q.pop();
//
if(gh.sum> k)
continue ;
for(i = 0; i< 4; i++)
{
xx =gh.x+d_x[i];
yy =gh.y+d_y[i];
if(grap[xx][yy]=='.')
{
cf.x =xx;
cf.y =yy;
cf.sum =gh.sum;
cf.f =i;
if(gh.f !=-1 && gh.f != i)
cf.sum = gh.sum +1;
if(cf.sum> k || pre[xx][yy] < cf.sum)
continue;
if(xx == g&& yy == h && cf.sum <= k)
{
printf("yes\n");
return;
}
q.push(cf);
pre[xx][yy]= cf.sum;
}
}
}
printf("no\n");
}
int main()
{
int t;
scanf("%d" ,&t);
while(t--)
{
scanf("%d%d" , &m , &n);
init();
int i , x ,y , j;
charch;
for(i=1;i<=n;i++)
{
getchar();
for( j=1;j<=m;j++)
{
scanf("%c",&ch);
grap[i][j]=ch;
}
//getchar();
}
scanf("%d %d%d %d %d" , &k , &y , &x , &h , &g);
if(x == g&& y == h)
printf("yes\n");
else bfs(x ,y);
}
return0;
}
给定一个m × n (m行,n列)的迷宫,迷宫中有两个位置,gloria想从迷宫的一个位置走到另外一个位置,当然迷宫中有些地方是空地,gloria可以穿越,有些地方是障碍,她必须绕行,从迷宫的一个位置,只能走到与它相邻的4个位置中,当然在行走过程中,gloria不能走到迷宫外面去。令人头痛的是,gloria是个没什么方向感的人,因此,她在行走过程中,不能转太多弯了,否则她会晕倒的。我们假定给定的两个位置都是空地,初始时,gloria所面向的方向未定,她可以选择4个方向的任何一个出发,而不算成一次转弯。gloria能从一个位置走到另外一个位置吗?
这题用普通的方法 不是超时 , 就是wa 。
老子我提交了50+
这题的数据确实是很牛逼啊 , 决对是设计出来的
到现在我还不知道我那个方法 , 为什么会wa
网上解题报告的解法:
这题用bfs来做 , 关键在于以一个什么方法来标记已经走过的点 , 这个地方 , 就是这个题目的关键 , 把这个问题解决了 ,这个题目也就A了
网上是这样做得 , 每次走的时候 , 都把这一方向的所以点走遍 , 然后把走过的点都标记 ,这样就能保证第一次走过这个点的时候的转弯次数一定是最少的。
代码:
#include
#include
#include
#include
using namespace std;
#define maxn 1100
char grap[maxn][maxn] ;
int
int n , m;
int d_x[4] = {-1 , 1, 0 , 0};
int d_y[4] = {0 , 0 , -1 , 1};
int g , h , k ;
int sum , cf;
typedef struct xyy
{
}edge;
void init()
{
}
void bfs(int x , int y)
{
}
int main()
{
}
下面是我自己的方法 , 一直wa , 一直不知道是哪错了
定义了一个数组pre , 来标记到达每个点的最小转弯次数 , 同时判断这个点能不能入队列(能不能继续往下走) ,只有这点的转弯次数会小于等于 , 当前这个点的最小转弯次数时 , 才能入队列
pre[xx][yy] < cf.sum
这里有一个bug , 假如当前这个点的最小转弯次数为x , 而现在你有到达这个点 , 且这个点的转弯次数也是x , 此时 ,这个点也要入队列 , 因为从这个点到目标点 , 可能还要再转弯一次 。
代码:
#include
#include
#include
#include
using namespace std;
#define maxn 1100
char grap[maxn][maxn] ;
int
int n , m;
int d_x[4] = {-1 , 1, 0 , 0};
int d_y[4] = {0 , 0 , -1 , 1};
int g , h , k ;
typedef struct xyy
{
}edge;
void init()
{
//
}
void bfs(int x , int y)
{
}
int main()
{
}