题目链接
给个学弟看代码,看了半天,给他打了注释,然后再将一些细节上改了下,还是挺累的,看代码吧,讲解和注释都附在上面了。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
//#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
struct MOGU
{
int x, y, time, boom; //(x,y),已经花费时间,爆炸时间
MOGU(int a=0, int b=0, int c=0, int d=0):x(a), y(b), time(c), boom(d) {} //这是初始化函数,有些编译器需要
};
int map[10][10];
int book[10][10];
bool vis[10][10][8]; //(x, y),第三个元素是指这个点的状态就是说距离爆炸时间的先后,要是之后有个更少的爆炸时间我们要更新我们的状态
int xx[4]={-1, 1, 0, 0};
int yy[4]={0, 0, -1, 1};
int main ()
{
int t, m, n, tx=0, ty=0, TIME, stx=0, sty=0; //非全局变量在定义的时候最好附上初始值
scanf ("%d", &t);
while (t--)
{
TIME=0;
//memset(book,0,sizeof(book));
memset(vis, false, sizeof(vis)); //布尔类型的初始化
scanf ("%d%d",&m,&n);
for (int i=1;i<=m;i++)
for (int j=1;j<=n;j++)
{
scanf ("%d", &map[i][j]);
if (map[i][j] == 2)
{
stx=tx=i;
sty=ty=j;
map[i][j] = 1; //让这个点成为可走点,为了之后的判断方便
}
}
queue<MOGU> q;
MOGU head, tail; //head是头,tail是下一个可走路径
head.x = stx;
head.y = sty;
head.boom = 6; //爆炸时间倒计时
vis[stx][sty][6] = true;
head.time = 0; //初始时间为0
q.push(head);
while (!q.empty())
{
head=q.front();
q.pop();
if (head.boom==1) //如果它就要爆炸,没法走下去
{
//q.pop(); //下次得到优先队列的队头元素后直接pop可以好记些。
continue;
}
for (int i=0;i<=3;i++)
{
tx = head.x + xx[i];
ty = head.y + yy[i];
if ( tx<1 || ty<1 || tx>m || ty>n || map[tx][ty]==0 ) continue; //你的book[i][j]遇到更优的解法没办法更新,所以可以用vis[i][j][boom]
if (map[tx][ty] == 1)
{
if(vis[tx][ty][head.boom-1]) continue;
tail.x = tx;
tail.y = ty;
tail.boom = head.boom - 1;
tail.time = head.time + 1;
q.push(tail);
vis[tx][ty][tail.boom] = true;
}
if (map[tx][ty]==3 && head.boom!=1)
{
TIME = head.time+1;
break;
}
if (map[tx][ty] == 4)
{
if(vis[tx][ty][6]) continue;
tail.x = tx;
tail.y = ty;
tail.boom = 6;
tail.time = head.time+1;
q.push(tail);
vis[tx][ty][6] = true;
}
}
if (TIME) break;
}
if (TIME) printf ("%d\n",TIME);
else printf ("-1\n");
}
return 0;
}