题意:从起点‘S’到终点‘T’经过的最少方格数,如果不能到达‘T’就输出-1。
思路:从起点BFS一下,把每个六边形的中心看做一个点。蜜蜂可以向六个方向移动,分别判断一下能否到达另一个相邻的六边形并判断是否是终点。记录一下最短的路径。
再总结一下做这个题遇到的一些困难:
①在输入的时候花了很长时间,因为使用gets可能导致堆栈溢出覆盖之前输入的内容,这次就用了cin.getline()输入,可是之前使用的次数不多,没有深入了解过cin.getline(),使用的不是很熟练,输入的时候发现输入的图形不能输出,于是上网查资料,是因为输入一行字符串之后敲回车,产生的换行符仍然滞留在输入流里,接着cin.getline()把回车读入进去,解决的方法就是使用cin.ignore(),这个函数的作用与getchar()吃掉空格一样,可是原文章中写道cin.ignore()的效果与getchar()效果一样,但是我把他俩替换掉之后还是不能输出图形,我也不知道为什么。(参考文章:https://www.cnblogs.com/zz-1120-wtenlb/p/10567599.html)
②解决输入问题之后交了一发结果TLE,又优化了一点,就是把vis数组去掉,其中vis数组表示某个六边形是否进入队列,因为在每组输入的时候都要对vis进行初始化,可能这会让费时间,那么直接在图上进行标记,把进入队列的点标记为 str [ i ] [ j ] = ‘#’。另外如果你是用cin,cout别忘了加ios::sync_with_stdio(false);
③其实也不用把某种路径的长度都求出,然后再求出所有路径中的最小值。直接第一次到达终点时结束就可以了。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
#define ll long long
#define lowbit(x) ((~x+1)&x)
using namespace std;
const int N = 1e3+5;
int mp[4*N][6*N];
char str[4*N][6*N];
int begin_x,begin_y;
int end_x,end_y;
int dir[7][2] = {{-2,0},{-1,3},{1,3},{2,0},{1,-3},{-1,-3}};
int t,n,m;
struct node {
int x,y,dis;
}pos,temp;
queue<node>q;
// int vis[4*N][6*N];
int bfs() {
int ans = 0x3f3f3f;
pos.x = begin_x;
pos.y = begin_y;
pos.dis = 1;
q.push(pos);
// vis[pos.x][pos.y] = 1;
str[pos.x][pos.y] = '#';
while(!q.empty()) {
node now = q.front();
q.pop();
if(now.x==end_x&&now.y==end_y) {
ans = min(ans,now.dis);
continue;
}
for(int i=0; i<6; i++) {
int tx,ty;
tx = now.x+dir[i][0];
ty = now.y+dir[i][1];
if(str[tx][ty]!='\\'&&str[tx][ty]!='/'&&str[tx][ty]!='-') {
temp.x = now.x+(2*dir[i][0]);
temp.y = now.y+(2*dir[i][1]);
temp.dis = now.dis+1;
if(str[temp.x][temp.y]!='#') {
// if(vis[temp.x][temp.y]==0) {
// vis[temp.x][temp.y] = 1;
str[temp.x][temp.y] = '#';
q.push(temp);
}
}
}
}
if(ans==0x3f3f3f) return -1;
else return ans;
}
int main() {
ios::sync_with_stdio(false);
cin>>t;
while(t--) {
// memset(vis,0,sizeof(vis));
int cnt=0;
cin>>n>>m;
n = 4*n+3;
m = 6*m+3;
cin.ignore();
for(int i=0; i<n; i++) {
cin.getline(str[i],m*n,'\n');
int len = strlen(str[i]);
for(int j=0; j<len; j++) {
if(str[i][j]=='S') {
begin_x = i;
begin_y = j;
}
else if(str[i][j]=='T') {
end_x = i;
end_y = j;
}
}
}
cout<<bfs()<<endl;
}
return 0;
}
//1
//3 3
// +---+ +---+
// / \ / \
// + p +---+ +---+
// \ n \ / \
// + + S +---+ T +
// / \ / /
// + +---+ + +
// \ \ / \
// +---+ +---+ +
// / /
// + +---+ + +
// \ / \
// +---+ +---+ +
// \ / \ /
// +---+ +---+
// 1
// 1 1
// +---+
// / \
// + +---+
// \ \
// + + S +
// \ /
// +---+