• poj2488深度搜索


    这道题说的是有一个象棋棋子马,走日字,问能从左上角开始,走的路径满足字典顺序(字母是字典顺序),问是否能

    走完所有的点,有则输出路径,注意,这里有的棋盘可以有很多种走法,但不是字典序列的,所以应该调整好搜索方案

    代码如下:

    #include <stdio.h>
    #include <string.h>
    //搜索过程中的路径
    int path[100][22];
    //搜索的下一跳方法
    int dr[8][2] = {{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};
    //标记搜索过程中,同一条路径中被标记的位置
    int mark[27][27];
    //行,列
    int p, q;
    //总的点数
    int total;
    //是否搜索成功
    int flag;
    
    //打印路径
    void print(){
    
    	int i,j;
    	for(i = 1;i <= total;i++){
    	
    		printf("%c%d", path[i][0] + 64, path[i][1]);
    	}
    	printf("
    ");
    }
    
    //用深度优先搜索查找合适的路径
    void dfs(int num){
    	
    	//当路径经过的点数为总数时,表示遍历完毕
    	if(num == total){
    		flag = 1;
    		print();
    		return;
    	}
    
    	if(flag){	
    		return ;
    	}
    
    	//保存当前搜索点的位置
    	int x = path[num][0];
    	int y = path[num][1];
    	int i,j;
    	int xn, yn;
    
    	//探询8个不同的方向,尝试是否能实现搜索
    	for(i = 0;i < 8;i++){
    		//下一跳位置
    		xn = x + dr[i][0];
    		yn = y + dr[i][1];
    
    		//满足条件则可以作为路径
    		if(xn >=1 && xn <= q && yn >=1 && yn <=p && !mark[xn][yn]){
    			//当前这条路径遍历过了,就不能再遍历了,所以标记为已遍历过
    			mark[xn][yn] = 1;
    			//更新下一跳坐标,这里比较重要,不能用num += 1,这样做的错误是,
    			//因为这是一个循环,如果在这次给更新了num,那么下一次就是下一个点
    			//了,这就不是在一个点(x,y)来搜索不同的方向,而是下一个点开始搜索了
    			//所以需要更换变量名
    			int nnum = num + 1;
    			path[nnum][0] = xn;
    			path[nnum][1] = yn;
    			//进行下一步搜索
    			dfs(nnum);
    			//根据递归的思想,在进入dfs()函数到这里调用dfs()函数为止,一直是一条路径
    			//进行搜索,到这里时,应该走别的路径了,所以应该恢复标记
    			mark[xn][yn] = 0;
    		}
    	}
    }
    int main(){
    	int t;
    	scanf("%d", &t);
    	int i = 1;
    	for(i = 1;i <= t;i++){
    	
    		scanf("%d%d", &p,&q);
    		total = p * q;
    		memset(path, 0, sizeof(path));
    		memset(mark, 0, sizeof(mark));
    
    		path[1][0] = 1;
    		path[1][1] = 1;
    		mark[1][1] = 1;
    
    		flag = 0;
    		printf("Scenario #%d:
    ",i);
    		dfs(1);
    
    		if(!flag){
    			printf("impossible
    ");			
    		}
    		if(i < t){
    			printf("
    ");
    		}
    	}
    	return 0;
    }


    关于dfs的理解


      准备条件:
             1、实现寻找目标步骤的方法,即移动的方法
             2、一个可以容纳所有可能节点的容器
             3、一个用于存储遍历结果的路径的容器
      方法:
             1、运用递归函数,逐个遍历,将节点选择的地方放在递归函数内部,
                 当检测到当前节点可行时,需标记为访问过,并将改节点存入路径中,
                 然后继续寻找下一个可能的节点,找完后,应将遍历过的节点恢复,
                 因为有可能走别的路径时,要遍历这个节点。


             2、在递归调用的同时,每次在入口测试是否达到目标状态,
                 如果达到目标状态,则将该路径做一个备份,但不能将其恢复默认值,
                 因为有的路径当不能到达目标节点时,会回溯到上一次,接着递归遍历,
                 所以会用到上一次的结果。

  • 相关阅读:
    【深入理解jvm笔记】Java发展史以及jdk各个版本的功能
    老罗Android视频教程(第一版)
    微软平台开发
    asp.net mvc 小结
    JavaScript代码段
    CSS代码片段
    c#代码片段
    Windows Phone 链接
    HttpRequest
    Win32
  • 原文地址:https://www.cnblogs.com/bbsno1/p/3279974.html
Copyright © 2020-2023  润新知