zoukankan      html  css  js  c++  java
  • dfs的剪枝优化

    两个剪枝问题

    1. 当两点的距离(需要走的步数)大于剩下的时间时 剪去

    2.奇偶剪枝问题

    如果起点到终点所需走的步数的奇偶性与时间奇偶性不同的时候 剪去

    起点到终点步数的奇偶性的判断

    首先 明确点的奇偶性判断 看起横纵坐标和为奇数还是偶数

    如果起点和终点的奇偶性相同 则步数为偶数 否则为奇数

    具体的代码实现    (start1+start2+end1+end2+time)%2==1  (如果两个数的奇偶性相同的话 两者和对2取余为0)

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<stdlib.h>
    using namespace std;
    int n,m,time;
    int flag;//判断是否有符合条件的搜索
    int visit[20][20];
    char mapp[20][20];
    int dir[4][2]={{0,1},{0,-1},{-1,0},{1,0}};//用于四个方向的遍历
    void dfs(int x,int y,int t)
    {
     int i;
     if(flag==1) return;//找到一个就退回。。 减少时间的消耗
     if(mapp[x][y]=='D')
     {
        if(t==time)
        flag=1;
        return;  //递归的终止条件 得多注意
        }
     if(t>=time) return;
     for(i=0;i<4;i++)
     {
      int xx,yy;
      xx=x+dir[i][0];
      yy=y+dir[i][1];
      if(xx<0||xx>=n||yy<0||yy>=m||mapp[xx][yy]=='X'||visit[xx][yy]==1) continue;
      visit[xx][yy]=1;
      dfs(xx,yy,t+1);//此时的i如果为全局变量的话 这里就对i的值做了改变
      visit[xx][yy]=0;
     }
    }

    int main()
    {
       int start1,start2,i,j,end1,end2;
       while(scanf("%d %d %d",&n,&m,&time)!=EOF)
      {
        if(n==0&&m==0&&time==0) break;
       memset(visit,0,sizeof(visit));
       flag=0;
       for(i=0;i<n;i++)
       {
        for(j=0;j<m;j++)
        {
           cin>>mapp[i][j];
        }
       }
       for(i=0;i<n;i++)//找到初始位置 终止位置 便于剪枝的进行
       {
        for(j=0;j<m;j++)
        {
         if(mapp[i][j]=='S')
         {
          start1=i;
          start2=j;
         } 
         if(mapp[i][j]=='D')
      {
        end1=i;
       end2=j;
      }
        }
       }
       if((abs(start1-end1)+abs(start2-end2))>time||(start1+start2+end1+end2+time)%2==1)//剪枝咯 第一个剪枝为如果剩下的距离大于时间 剪去 第二个剪枝是奇偶减枝
       {
       printf("NO ");
       continue;
       }
       visit[start1][start2]=1;
       dfs(start1,start2,0);
       if(flag==1) printf("YES ");
       else printf("NO ");
     }
     return 0;
    }

    这次优化主要就是应用了剪枝  加油

  • 相关阅读:
    十大编程算法助程序员走上高手之路
    软件流程图规范
    统一软件开发过程(rup)理解
    Java 数组基础
    软件开发生命周期模型 瀑布模型、增量模型、原型模型、螺旋模型、喷泉模型总结
    UML(5)——协作图
    时序图、活动图、状态图、协作图的区别
    面向对象分析设计-------02UML+UML各种图形及作用
    ExecutorService的十个使用技巧
    使用guava带来的方便
  • 原文地址:https://www.cnblogs.com/z1141000271/p/5364018.html
Copyright © 2011-2022 走看看