题意:
Edward is trapped in a grid maze! A grid maze is an n×n square maze where each cell is either empty, or is a wall. Edward can go from one cell to another only if both cells are empty and have a common side.
The starting position of Edward is located at the si-th row and the sj-th column of the maze. In order to escape, Edward has to first get the key located at the ki-th row and the kj-th column of the maze, and then move to the exit located at the ei-th row and the ej-th column of the maze. Of course, Edward can move into (ei, ej) even if he hasn’t get the key yet, but he can’t escape from the maze through the exit at that time.
It takes Edward 1 second to move from one cell to another. Can you help Edward calculate the minimum time he needs to escape from the maze?
输入:
There are multiple test cases. The first line of input contains an integer T (1 ≤ T ≤ 10), indicating the number of test cases. For each test case:
The first line contains seven integers n, si, sj, ki, kj, ei, ej (2 ≤ n ≤ 100, 1 ≤ si, sj, ki, kj, ei, ej ≤ n), indicating the size of the maze, the starting position, the position of the key and the position of the exit.
For the following n lines, the i-th line contains n integers ai, 1, ai, 2, …, ai, n (0 ≤ ai, j ≤ 1). ai, j indicates the cell at the i-th row and the j-th column of the maze. If ai, j equals 0, then the cell is empty, otherwise the cell is blocked.
It’s guaranteed that (si, sj) ≠ (ki, kj), (si, sj) ≠ (ei, ej) and (ki, kj) ≠ (ei, ej). None of the starting position, the position of the key and the position of the exit is blocked. And it’s guaranteed that Edward can always escape from the maze.
输出:
For each test case output one line containing one integer, indicating the shortest time Edward needs to escape.
样例输入:
2
3 1 1 3 1 3 3
0 0 0
0 1 0
0 1 0
2 1 1 1 2 2 2
0 0
1 0
样例输出:
8
2
The optimal path for Edward in the first test case is (1, 1) -> (2, 1) -> (3, 1) -> (2, 1) -> (1, 1) -> (1, 2) -> (1, 3) -> (2, 3) -> (3, 3), so the answer is 8.
解题思路:
题目的意思就是你刚开始在(si,sj),你要先去(ki,kj),然后再从(ki,kj)到(ei,ej),问最短的时间是多少。
我用dfs写结果超时了,就用bfs了,但是我太讨厌用bfs了,还要用队列和结构体,太麻烦了。
就是你要一个个搜,找到最小的就行啦
程序代码:(dfs)-TLE
#include<bits/stdc++.h>
using namespace std;
const int dirx[4]={-1,1,0,0}//确定四个方向
,diry[4]={0,0,1,-1};
const int N=100+10;
const int INF=0x3f3f3f3f;
int n,ans=INF,sum=0;
int s[N][N],a[N][N];//s记录迷宫图,a记录是否被访问过
void dfs(int x,int y,int ax,int ay)
{
if(x==ax&&y==ay)
{
ans=min(ans,sum);
return ;
}
for(int i=0;i<4;i++)//依次访问该点周围四个方向
{
int nx=x+dirx[i];
int ny=y+diry[i];
if(nx>=1&&nx<=n&&ny>=1&&ny<=n&&s[nx][ny]==0&&a[nx][ny]==0)//前四个为判断是否在迷宫中 最后一个是判断该点是否被访问过
{
a[nx][ny]=1;
sum++;
dfs(nx,ny,ax,ay);//是没访问过的点并且是可行点,就继续搜索
sum--;
a[nx][ny]=0;//回溯,重新置为0,方便下次访问
}
}
return ;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
memset(s,0,sizeof(s));
memset(a,0,sizeof(a));
ans=INF;
sum=0;
int sx,sy,kx,ky,ex,ey;
scanf("%d %d %d %d %d %d %d",&n,&sx,&sy,&kx,&ky,&ex,&ey);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&s[i][j]);
a[sx][sy]=1;
dfs(sx,sy,kx,ky);
int temp=ans;
memset(a,0,sizeof(a));
ans=INF;
sum=0;
a[kx][ky]=1;
dfs(kx,ky,ex,ey);
int temp1=ans;
printf("%d\n",temp+temp1);
}
return 0;
}
程序代码:(bfs)-AC
#include<bits/stdc++.h>
using namespace std;
struct node{
int x,y; //当前结点在图上的坐标
int step; //表示到达当前结点所需的步数
};
const int dir[4][4]={{0,1},{1,0},{0,-1},{-1,0}};//确定四个方向
const int N=100+10;
int s[N][N],a[N][N];//s记录迷宫图,a记录是否被访问过
int n;
int bfs(int x,int y,int ax,int ay){
node start;
start.x = x,start.y = y;
start.step = 0;
memset(a,0,sizeof(a));
queue<node> q;
q.push(start); //将起点进行入队操作。
a[start.x][start.y] = 1;
while(!q.empty()){
node now = q.front();
q.pop(); //将当前节点进行出队。
for(int i=0;i<4;i++){ //每次循环分别对当前节点对四周节点进行访问
int nx = now.x+dir[i][0];
int ny = now.y+dir[i][1];
node next;//即将入队的节点
if(a[nx][ny]==0&&s[nx][ny]==0&&nx>=1&&nx<=n&&ny>=1&&ny<=n){
a[nx][ny] = 1;//将已访问节点进行标注
next.x = nx;
next.y = ny;
next.step = now.step+1;
q.push(next); //将下一个节点进行入队操作
}
if(nx==ax&&ny==ay){ //当已经到达终点时返回
return next.step; //返回从初始点到终点所需要的步数
}
}
}
return 0; //查找失败没有找到对应的路线
}
int main(){
int T;
scanf("%d",&T);
while(T--){
// memset(s,0,sizeof(s));
// memset(a,0,sizeof(a));
int sx,sy,kx,ky,ex,ey;
scanf("%d %d %d %d %d %d %d",&n,&sx,&sy,&kx,&ky,&ex,&ey);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
scanf("%d",&s[i][j]);
int ans=bfs(sx,sy,kx,ky);
int ans1=bfs(kx,ky,ex,ey);
printf("%d\n",ans+ans1);
}
return 0;
}