题目给出的地图中共有四类东西:玉米地、草地、传送门、牛。
其中,玉米地不能走,其余的位置都能走,每走一步花费一个单位的时间,到达传送门时会被传送至另一扇相同类型传送门初,且不会花费时间。
我的思路是设一个标记数组来记录走过地方,由于传送门可以使用两次,刚好一去一回,两个传送门的坐标都只被标记了一次,所以设数组来记录路径在这里应该是没有问题的。
很明显,这道题需要使用BFS。
把“找出起点和终点”的工作放在输入中会减少不少的程序累赘工作,找到起点和终点并将它们标记后将起点压入队列并做好标记,而后就可以开始进行你的bfs了
选取好一个点后对其向四个方向进行扩展,记得做好剪枝处理。
只是最后还是存在问题,我暂时还没发现,还需要后续进行修改。。。
(这里放上代码只是做个思路参考,直接交是错的)
#include<stdio.h>
char map[1000][1000];//存储地图
int book[1000][1000];//定义标记数组
int n,m,head=0,tail=0,x1,y2;
int shi[2]={-1,-1},mo[2]={-1,-1};
//定义方向数组
int next[4][2]={{0,1},{0,-1},{1,0},{-1,0}};//右、左、上、下
struct abc
{
int x,y,step;
}que[500000];
void deliver(int x,int y,char k)//传送门转点
{
int k1,k2;
for(k1=0;k1<n;k1++)
{
for(k2=0;k2<m;k2++)
{
if( k1 != x && k2 != y && map[k1][k2] == k)
{
x1=k1;
y2=k2;
return ;
}
}
}
}
int main()
{
int i,j;
scanf("%d %d",&n,&m);
for(i=0;i<n;i++)
scanf("%s",map[i]);
for(i=0;i<n;i++)//找出起点和终点
{
for(j=0;j<m;j++)
{
if(map[i][j] == '@')
{
shi[0]=i;
shi[1]=j;
}
if(map[i][j] == '=')
{
mo[0]=i;
mo[1]=j;
}
if(shi[0] !=-1 && mo[0] != -1)
break;
}
}
// printf("shi[0]=%d shi[1]=%d\nmo[0]=%d mo[1]=%d\n",shi[0],shi[1],mo[0],mo[1]);
book[shi[0]][shi[1]]=1;//对起点标记
que[tail].x=shi[0];//将起点压入队列
que[tail].y=shi[1];
que[tail++].step=0;//初始步数为0
while( head < tail)
{
for(i=0;i<4;i++)//分别向四个方向遍历
{
int tx,ty;
tx=que[head].x+next[i][0];
ty=que[head].y+next[i][1];
//剪枝
if(tx < 0 || tx >= n || ty < 0 || ty >= m|| book[tx][ty] != 0 || map[tx][ty] == '#')
continue;
que[tail].x=tx;//将可取点压入队列
que[tail].y=ty;
que[tail].step=que[head].step+1;
if(map[tx][ty] >='A' && map[tx][ty] <='Z')//判断是否在传送门上
{
deliver(tx,ty,map[tx][ty]);
que[tail].x=x1;
que[tail].y=y2;
}
if(tx == mo[0] && ty == mo[1])//判断是否到终点
{
printf("%d\n",que[tail].step);
return 0;
}
tail++;//尾指针后移
}
head++;//头指针后移
}
return 0;
}
昨天说这道题的代码还有点瑕疵。
找出原因后明白是因为我的代码是直接修改原地图,这样就造成了邻近的单词或交错的单词会有误判的情况。
要修改也很简单,加上一个标记数组就好了。
#include<stdio.h>
int n;
char a[1000][1000],k1[2000],k2[2000];
//定义方向常量数组
int book[1000][1000];//用于标记数组
int next[8][2]={{0,1},{0,-1},{1,0},{-1,0},{-1,1},{-1,-1},{1,1},{1,-1}};
//右、左、上、下、下右、下左、上右、上左
void dfs(int x,int y,int k,int flag)
{
if(x < 0 ||x >=n || y < 0 || y >=n)
return;
int i,j;
if(k == -100)
{
for(i=0;i<8;i++)
{
int tx,ty;
tx=x+next[i][0];
ty=y+next[i][1];
if(tx < 0 || tx >= n || ty < 0 || ty >= n)
continue;
if(a[tx][ty] == 'i')
dfs(tx,ty,i,1);
k=-100;
}
}
if(k != -100)
{
int tx,ty,i1;
tx=x+next[k][0];
ty=y+next[k][1];
if(tx < 0 || tx >= n || ty < 0 || ty >= n)
return;
if(a[tx][ty] == 'z' && flag== 1)
dfs(tx,ty,k,2);
if(a[tx][ty] == 'h' && flag == 2)
dfs(tx,ty,k,3);
if(a[tx][ty] == 'o' && flag == 3)
dfs(tx,ty,k,4);
if(a[tx][ty] == 'n' && flag == 4)
dfs(tx,ty,k,5);
if(a[tx][ty] == 'g' && flag == 5)
{
book[tx][ty]='7';
book[tx-next[k][0]][ty-next[k][1]]='6';
book[tx-2*next[k][0]][ty-2*next[k][1]]='5';
book[tx-3*next[k][0]][ty-3*next[k][1]]='4';
book[tx-4*next[k][0]][ty-4*next[k][1]]='3';
book[tx-5*next[k][0]][ty-5*next[k][1]]='2';
book[tx-6*next[k][0]][ty-6*next[k][1]]='1';
return ;
}
}
return ;
}
int main()
{
scanf("%d",&n);
int i,j,k=0;
for(i=0;i<n;i++)
scanf("%s",a[i]);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(a[i][j] == 'y')//记录所有'y'字母的坐标
{
k1[k]=i;
k2[k]=j;
k++;
}
}
}
for(i=0;i<k;i++)
dfs(k1[i],k2[i],-100,0);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
if(book[i][j] == '1')
a[i][j]='y';
else
{if(book[i][j] == '2')
a[i][j]='i';
else
{if(book[i][j] == '3')
a[i][j]='z';
else
{if(book[i][j] == '4')
a[i][j]='h';
else
{if(book[i][j] == '5')
a[i][j]='o';
else
{if(book[i][j] == '6')
a[i][j]='n';
else
{if(book[i][j] == '7')
a[i][j]='g';
else
a[i][j]='*';
}}}}}}
}
}
for(i=0;i<n;i++)
{printf("%s",a[i]);
if(i != n-1)
printf("\n");}
return 0;
}
( + 记单词 2.5 h )