1647: 穿越雷区
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了1647: 穿越雷区相关的知识,希望对你有一定的参考价值。
题目描述
X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废。
某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?
某坦克需要从A区到B区去(A,B区本身是安全区,没有正能量或负能量特征),怎样走才能路径最短?
已知的地图是一个方阵,上面用字母标出了A,B区,其它区都标了正号或负号分别表示正负能量辐射区。
例如:
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -
例如:
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -
坦克车只能水平或垂直方向上移动到相邻的区。
输入
输入第一行是一个整数n,表示方阵的大小, 4<=n<100
接下来是n行,每行有n个数据,可能是A,B,+,-中的某一个,中间用空格分开。
A,B都只出现一次。
输出
要求输出一个整数,表示坦克从A区到B区的最少移动步数。
如果没有方案,则输出-1
样例输入
5
A + - + -
- + - - +
- + + + -
+ - + - +
B + - + -
样例输出
10
提示
来源
conclude:
1.两个回溯(标记需要“切记:不能走原路,否则死循环”,递归for循环分类需要);
2.找最小问题用技巧减少递归次数;
3.读取空格隔开的字符不能用scanf;
#include <iostream> #include <cstring> using namespace std; int mi=1000; char map[100][100]; int mark[100][100]={0}; int x,y,n; int x0,y0; int a[4]={0,0,1,-1}; //这样下标就从0开始了。 int b[4]={1,-1,0,0}; void dfs(int k) { if(x<1||y<1||x>n||y>n) //出界递归结束 { return; } if(k>mi) // !!!关键所在!!! return; //找最小,超过最小就不用找了,递归结束 if(map[x][y]==‘B‘) { mi=k; return; //找到了也要结束递归 } mark[x][y]=1; for(int i=0;i<=3;i++) { if(map[x+a[i]][y+b[i]]!=map[x][y]&&!mark[x+a[i]][y+b[i]]) { x+=a[i]; y+=b[i]; dfs(k+1); x-=a[i]; //循环内部回溯 y-=b[i]; } } mark[x][y]=0; //标记,不能走原路!!!!!循环外部也不要回溯 !!! } int main() { cin>>n; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { cin>>map[i][j]; //!!!!不能用scanf%c,他可以读取空格。 if(map[i][j]==‘A‘) { x=i; y=j; } } } dfs(0); if(mi==1000) cout<<-1; else cout<<mi; }
以上是关于1647: 穿越雷区的主要内容,如果未能解决你的问题,请参考以下文章