本题的陷井在于:1.Y不能走M的位置并且M不能走Y的位置 2.每个@必须被Y和M分别访问一次才能是正确的时间值
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=205;
const int inf=0x3f3f3f3f;
int n,m;
char mapp[maxn][maxn];
int time[2][maxn][maxn];//[0]表示时间,[1]标志是不是正确
int vis[maxn][maxn];
struct node
{
int x;
int y;
int num;
};
queue<node>que;
int t;//最小时间
int dir[4][2]= {{0,-1},{0,1},{1,0},{-1,0}};
void bfs()
{
node cur,nex;
while(!que.empty())
{
cur=que.front();
que.pop();
for(int i=0; i<4; i++)
{
int xx=cur.x+dir[i][0];
int yy=cur.y+dir[i][1];
if(xx>=0&&yy>=0&&xx<n&&yy<m&&vis[xx][yy]==0&&mapp[xx][yy]!='#'&&mapp[xx][yy]!='Y'&&mapp[xx][yy]!='M')
{
if(mapp[xx][yy]=='@')
{
time[1][xx][yy]++;
time[0][xx][yy]+=(cur.num+1);
///cout<<"坐标"<<xx<<","<<yy<<"最小时间修改为"<<time[0][xx][yy]<<endl;//检验
}
nex.x=xx;
nex.y=yy;
nex.num=cur.num+1;
vis[xx][yy]=1;
que.push(nex);
}
}
}
t=inf;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
if(mapp[i][j]=='@'&&time[1][i][j]==2)
t=min(t,time[0][i][j]);
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
//memset能赋值0和-1
memset(time,0,sizeof(time));
node pp;
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
cin>>mapp[i][j];
}
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
if(mapp[i][j]=='Y'||mapp[i][j]=='M')
{
//节点入队
memset(vis,0,sizeof(vis));
pp.x=i;
pp.y=j;
pp.num=0;
vis[i][j]=1;
while(!que.empty())
{
que.pop();
}
que.push(pp);
bfs();
}
cout<<t*11<<endl;
}
return 0;
}
当然,必须注意一个很重要的问题:0x3f3f3f3f表示数字为1061109567在10位以上,但是0x3f3f3f(少了一个3f),导致无穷大的数量级降低到了4144959,不再符合一般题目中“无穷”的要求,所以结论是:
用0x3f3f3f3f表示无穷是写4个"3f"!!!