如何拯救007

  一开始看到这题感觉挺难的,没什么头绪,然后我上网查了一些不同的做法,还有一个特别好的图解,看了之后感觉思路就清晰很多了。

  这个是我看到一个很不错的图解,可以帮助我们更好地理解题目。

  这个则是我做这道题的参考,我觉得比较容易理解,是很不错的参考。

  题目分析

  1. 首先要清楚我们要写的子函数,有save007,save007里面包含函数firstjump,jump,isave和DFS。
  2. 可以分为以下几种情况:
  • 007的步长d>=50-7.5=42.5时,可以直接跳出岛
  • firstjump:判断能否跳到第一个点a,即d+7.5>=sqrt(x*x+y*y)
  • isave:判断007能否从点a直接跳到岸边,即d>=50-|x|或d>=50-|y|
  • jump:判断007能否从点a跳到另一个点b,即d>=sqrt((x1-x2)^2+(y1-y2)^2),如果不能,利用递归,返回上一点继续查找。

 

首先是建立一个结构体,记录鳄鱼的位置

struct point{
//存储鳄鱼的位置 
    int x;
    int y;
}point[max];

 

然后我这题用来矩阵的方法,所以还有个初始化矩阵

 void resetvisited()
 {//初始化标记矩阵 
     for(int i=0; i<max; i++)
         visited[i] = 0;
  }

 

接着是firstjump函数,判断能否跳到第一个点a,这里的yes和no我在一开始也做了定义

 #define max 100
 #define Yes 1
 #define No 0

 

int firstjump(int i)
{//判断能否从岛上跳到一只鳄鱼上 
    int x = point[i].x;
    int y = point[i].y;
    
    if( (d+7.5)*(d+7.5) >= (x*x+y*y) )            
        return Yes;
    else
        return No;
}

 

接着判断能否从a点直接跳到湖岸,当007步长大于a点到湖岸的距离时,说明可以到达

int isave(int i)
{//判断在一条鳄鱼上时能否跳到岸边 
    int x = point[i].x;
    int y = point[i].y;
    
    if(x<0)
        x=-x;
    
    if(y<0)
        y=-y;
        
    if(d>50-x || d>50-y)
        return Yes;
    else
        return No;
}

 

jump函数,判断能否从一点跳到另一点上

int jump(int i, int j)
{//判断007能否从一条鳄鱼跳到另一条鳄鱼上 
    int x1 = point[i].x;
    int y1 = point[i].y;
    int x2 = point[j].x;
    int y2 = point[j].y;
    
    if(d*d >= (x1 - x2)*(x1 - x2) + (y1 - y2)*(y1 - y2))
        return Yes;
    else
        return No;
}

 

深搜DFS

int DFS(int i)
{
    int answer;
    visited[i] = true;
    
    if(isave(i)) 
        answer = Yes;
    else
    {
        for(int k=0; k<n; k++)
        {
            if(!visited[k] && jump(i, k))    //如果改点未被访问且能从i点跳到k点 
            {
                answer = DFS(k);
                if(answer == Yes)
                    break;
            }
        }
    }        
                
    return answer;
}

 

最后是save007,利用上面几个函数递归

void save007()
{
    int answer;
    resetvisited();        //初始化矩阵
    
    for(int i=0; i<n; i++)
    {
        if(!visited[i] && firstjump(i))//如果该点未被访问且能跳到该点 
            answer = DFS(i);
            if(answer == Yes)
                break;
     } 
     
     if(answer == Yes)
         cout<<"Yes";
    else
        cout<<"No";
}

 

总结

  这道题主要是利用我们这章学习的图的遍历:DFS和BFS。主要是要掌握好如何遍历图,而且我们这学期学的像树,数组,链表等等,遍历都是很重要的一个内容,很多操作都是在遍历上完成的。

上次的目标完成的不错,所以我会继续看回以前做过的题,做出每章的知识总结。

 

posted @ 2019-05-19 15:06  zzpikaqiu  阅读(299)  评论(1编辑  收藏  举报