之前我写的时候是:每找到一个‘@’就广搜一次,如果这样写有多少个‘@’就会广搜几次,这样就超时了。我队友告诉我应该打个表,这个方法确实不错。因为'Y'和'M'是唯一的,我通过这两个点分别广搜一次,对所有到达‘@’的情况打个表,这样就节省了很多时间。具体看代码吧。
#include<cstdio>
#include<stdio.h>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#define INF 0x3f3f3f3f
#define MAX 1005 using namespace std; int n,m,vis[MAX][MAX],v[][]= {{,},{,-},{,},{-,}},Time[MAX][MAX],b[MAX][MAX];
char Map[MAX][MAX]; struct node
{
int x,y,step;
}; void BFS(int sx,int sy)
{
memset(vis,,sizeof(vis));
queue<node>Q;
node a,next;
a.x=sx;
a.y=sy;
a.step=;
Q.push(a);
vis[sx][sy]=;
while(!Q.empty())
{
a=Q.front();
Q.pop(); if(Map[a.x][a.y]=='@' && !b[a.x][a.y])//数组b记录是否到达过这个‘@’
{
b[a.x][a.y]=;
Time[a.x][a.y]+=a.step*;
next.x=sx;
next.y=sy;
next.step=;
Q.push(next);
} for(int i=; i<; i++)
{
next.x=a.x+v[i][];
next.y=a.y+v[i][]; if(next.x>= && next.x<n && next.y>= && next.y<m && Map[next.x][next.y]!='#' && !vis[next.x][next.y])
{
vis[next.x][next.y]=;
next.step=a.step+;
Q.push(next);
}
}
}
} int main()
{
int i,j,ans,x1,x2,y1,y2;
while(scanf("%d%d",&n,&m)!=EOF)
{
ans=INF;
for(i=; i<n; i++)
{
scanf("%s",Map[i]);
} for(i=; i<n; i++)
{
for(j=; j<m; j++)
{
if(Map[i][j]=='Y')
{
x1=i;
y1=j;
} if(Map[i][j]=='M')
{
x2=i;
y2=j;
}
}
} memset(b,,sizeof(b));
memset(Time,,sizeof(Time));
BFS(x1,y1);//对‘Y’到达‘@’进行广搜
memset(b,,sizeof(b));
BFS(x2,y2);对‘M’到达‘@’进行广搜 for(i=;i<n;i++)
{
for(j=;j<m;j++)
{
if(Time[i][j]!=)
ans=min(ans,Time[i][j]);
}
} printf("%d\n",ans);
}
return ;
}