穿越雷区
题目描述
X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废。
某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?
已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。
例如:
坦克车只能水平或垂直方向上移动到相邻的区。
输入
输入第一行是一个整数n,表示方阵的大小, 4<=n<100
接下来是n行,每行有n个数据,可能是A,B,+,-中的某一个,中间用空格分开。
输入保证A,B都只出现一次。
输出
要求输出一个整数,表示坦克从A区到B区的最少移动步数。
如果没有方案,则输出-1
样例输入
5
| A + - + -
| - + - - +
| - + + + -
| + - + - +
| B + - + -
样例输出 Copy
10
解法
解法一 DFS
#include <iostream>
#include <vector>
#include <cstdio>
#include <cmath>
using namespace std;
char map[101][101];
int dir[4][2]={{1,0},{0,-1},{-1,0},{0,1}};
//int dir[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int flag=0; //1表示+ 2表示-
bool vis[101][101];
int ans=0;
int Min=99999;
int dfs(int index,int x,int y){
int nx,ny;
// cout<<x<<' '<<y<<' '<<index<<endl;
// cout<<flag<<' '<<map[x][y];
if(map[x][y]=='B'){
// cout<<"--------------------"<<Min<<' '<<ans<<endl;
if(Min>index) Min=index;
return 0;
}
for(int i=0;i<4;i++){
nx=x+dir[i][0];
ny=y+dir[i][1];
if(!vis[nx][ny]){
// if(map[nx][ny]=='B'){
// if(Min>index+1) Min=index+1;
// cout<<"--------------------"<<Min<<' '<<ans<<endl;
// return 0;
// }
if((map[nx][ny]=='+' && map[nx][ny]!=map[x][y]) || map[nx][ny]=='B'){
vis[nx][ny]=true;
ans++;
flag=1;
dfs(index+1,nx,ny);
vis[nx][ny]=false;
ans--;
}
else if((map[nx][ny]=='-' && map[nx][ny]!=map[x][y]) ||map[nx][ny]=='B' ){
vis[nx][ny]=true;
ans++;
flag=2;
dfs(index+1,nx,ny);
vis[nx][ny]=false;
ans--;
}
}
}
return 0;
}
int main(){
int n;
int x0,y0;
scanf("%d",&n);
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++){
vis[i][j]=true;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
vis[i][j]=false;
cin>>map[i][j];
if(map[i][j]=='A'){
x0=i;
y0=j;
}
}
}
dfs(0,x0,y0);
cout<<Min;
return 0;
}
这个会超时,只过80%的数据
解法二 BFS
#include<iostream>
#include<queue>
using namespace std;
const int MAX=105;
int n;
char map[MAX][MAX];
bool vis[MAX][MAX];
int go[][2]={{1,0},{0,-1},{0,1},{-1,0}};//四个可行走方向
struct Point
{
int x,y,step;
Point(int a,int b,int c)
{ x=a,y=b,step=c; }
};
void bfs(int x,int y)
{
queue<Point> q;
Point p(x,y,0);
q.push(p);
vis[x][y]=true;
while(!q.empty())
{
Point temp=q.front();q.pop();
for(int i=0;i<4;i++)
{
int new_x=temp.x+go[i][0],new_y=temp.y+go[i][1];
if(new_x>=1 && new_x<=n && new_y>=1 && new_y<=n
&& !vis[new_x][new_y] && map[temp.x][temp.y]!=map[new_x][new_y])
{
if(map[new_x][new_y]=='B'){
cout<<temp.step+1;
return;
}
vis[new_x][new_y]=true; //标记为已走
q.push(Point(new_x,new_y,temp.step+1));
}
}
}
//如果队列中所有点都走完了也没能找到一个最短的移动方案就直接输出-1
cout<<-1<<endl;
}
int main()
{
int start_x,start_y;
cin>>n;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
cin>>map[i][j];
if(map[i][j]=='A')
start_x=i,start_y=j;
}
bfs(start_x,start_y);
return 0;
}
BFS解法摘自:https://blog.csdn.net/the_ZED/article/details/104094356