码迷,mamicode.com
首页 > 其他好文 > 详细

1647: 穿越雷区

时间:2017-08-25 17:44:00      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:一个   死循环   结束   arch   最小   递归   ==   技巧   表示   

题目描述

X星的坦克战车很奇怪,它必须交替地穿越正能量辐射区和负能量辐射区才能保持正常运转,否则将报废。
某坦克需要从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

提示

 

来源

蓝桥杯2015年决赛

 

 

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: 穿越雷区

标签:一个   死循环   结束   arch   最小   递归   ==   技巧   表示   

原文地址:http://www.cnblogs.com/biggan/p/7428928.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!