题目大意:题目戳我
翻译过来就是“猪坚强”走出去,但是经过“."时不需要花费步数,而经过“*”需要花费一步,“#”表示障碍。
题目思路:
因为步数不一样,考虑用优先队列来保存经过的步数,每次步数小的先出队;
收获:
在结构体里重载优先队列的运算符时,只能对"<"号进行重载,不然会报错;
struct COO
{
int x,y;
int num;
friend bool operator<(COO a,COO b)
{
return a.num>b.num;
}//步数少的优先
}start,nxt,mid;
如果想要步数大的优先出来:
struct COO
{
int x,y;
int num;
friend bool operator<(COO a,COO b)
{
return a.num<b.num;
}//步数大的优先
}start,nxt,mid;
题目代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#define maxn 105
using namespace std;
int dx[4]={1,0,-1,0};
int dy[4]={0,-1,0,1};
int vis[maxn][maxn];
struct COO
{
int x,y;
int num;
friend bool operator<(COO a,COO b)
{
return a.num>b.num;
}//步数少的优先
}start,nxt,mid;
priority_queue<COO>q;
int main(void)
{
int t,m,n;
char ch[maxn][maxn];
int a,b;
int flag;
scanf("%d",&t);
while(t--)
{
while(!q.empty())
q.pop();
flag=1;
memset(vis,0,sizeof(vis));
memset(ch,0,sizeof(ch));
//初始化
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
{
scanf("%s",ch[i]);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
if(ch[i][j]=='@')
{
a=i;
b=j;//第a行第b列
}
}
//printf("a: %d,b: %d\n",a,b);
start.x=a;start.y=b;
start.num=0;
q.push(start);
vis[a][b]=1;
while(!q.empty())
{
mid=q.top();
q.pop();
if(mid.x==0||mid.x==(n-1)||mid.y==0||mid.y==(m-1))
{
//printf("mmmm\n");
flag=0;
printf("%d\n",mid.num);
break;
//goto mm;
}
for(int i=0;i<4;i++)
{
int nx=mid.x+dx[i];
int ny=mid.y+dy[i];
//printf("mid.x: %d,mid.y: %d\n",mid.x,mid.y);
//printf("nx: %d,ny: %d\n",nx,ny);
if(nx>=0&&nx<n&&ny>=0&&ny<m&&!vis[nx][ny]&&ch[nx][ny]!='#')
{
if(ch[nx][ny]=='.')//步数+0
nxt.num=mid.num;
else if(ch[nx][ny]=='*')//步数+1
nxt.num=mid.num+1;
nxt.x=nx;
nxt.y=ny;
vis[nx][ny]=1;
q.push(nxt);
}
}
}
if(flag)
printf("-1\n");
}
}
呼呼