2018.07.29(搜索)学习DFS算法小记
Posted mokou
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2018.07.29(搜索)学习DFS算法小记相关的知识,希望对你有一定的参考价值。
参考网站:https://blog.csdn.net/ldx19980108/article/details/76324307
这个算法还算好理解一点吧,有递归的思路,理解了一个上午~
感觉还不错,看完代码基本上就懂了,可以自己实现了
/* Fire Net */ /*Suppose that we have a square city with straight streets. A map of a city is a square board with n rows and n columns, each representing a street or a piece of wall. A blockhouse is a small castle that has four openings through which to shoot. The four openings are facing North, East, South, and West, respectively. There will be one machine gun shooting through each opening. Here we assume that a bullet is so powerful that it can run across any distance and destroy a blockhouse on its way. On the other hand, a wall is so strongly built that can stop the bullets. The goal is to place as many blockhouses in a city as possible so that no two can destroy each other. A configuration of blockhouses is legal provided that no two blockhouses are on the same horizontal row or vertical column in a map unless there is at least one wall separating them. In this problem we will consider small square cities (at most 4x4) that contain walls through which bullets cannot run through. The following image shows five pictures of the same board. The first picture is the empty board, the second and third pictures show legal configurations, and the fourth and fifth pictures show illegal configurations. For this board, the maximum number of blockhouses in a legal configuration is 5; the second picture shows one way to do it, but there are several other ways. Your task is to write a program that, given a description of a map, calculates the maximum number of blockhouses that can be placed in the city in a legal configuration. The input file contains one or more map descriptions, followed by a line containing the number 0 that signals the end of the file. Each map description begins with a line containing a positive integer n that is the size of the city; n will be at most 4. The next n lines each describe one row of the map, with a ‘.‘ indicating an open space and an uppercase ‘X‘ indicating a wall. There are no spaces in the input file. For each test case, output one line containing the maximum number of blockhouses that can be placed in the city in a legal configuration. Sample input: 4 .X.. .... XX.. .... 2 XX .X 3 .X. X.X .X. 3 ... .XX .XX 4 .... .... .... .... 0 Sample output: 5 1 5 2 4*/ #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <cmath> using namespace std; /*拿到这道题目,我肯定是不会的啦,所以我去摆渡了一下具体实现方法,用到的是dfs算 法,简单看了例题,需要用到的是遍历整个数组。按照这个思维模式的话,我觉得这道题 也可以用递归的方法做*/ //先测试一下输入会不会出错 /*有地图就会有二维数据,但记录step的时候依旧要使用单个数字,这时候纵坐标X=step/ len+1,横坐标Y=step%len+1,如果二维地图是从(1,1)开始输入的话*/ char a[5][5]; int Count,len; int judge( int x , int y) { int i; //判断上面有没有碉堡或者墙壁,此时的Y大小不变 for ( i=x-1 ; i>0 ; i-- ) { if ( a[i][y] == ‘O‘ ) return 0;//上面有堡垒了,不满足,退出函数 if ( a[i][y] == ‘X‘ ) break;//上面有墙壁了,满足,跳出循环 } //判断左边有没有碉堡或者墙壁,此时的X大小不变 for ( i=y-1 ; i>0 ; i-- ) { if ( a[x][i] == ‘O‘ ) return 0;//左边有堡垒了,不满足,退出函数 if ( a[x][i] == ‘X‘ ) break;//左边有墙壁了,满足,跳出循环 } return 1;//上面条件两者皆满足,该点满足条件,返回1 } void dfs(int step, int num )//step是当前位置,num是在这个分支下最大的count { if ( step==len*len ) //如果发现这时候达到了上限,要开始回溯到上个岔路口 { if ( num > Count ) Count=num;//如果这种情况下碉堡比较多的话替换 return; } int x=step/len+1 ,y=step%len+1;//数字向二维坐标转换,这里是从(1,1)开始输入的 if ( a[x][y]==‘.‘ && judge(x,y) )//如果这个点是个空地的话,且前面没碉堡的话 { a[x][y]=‘O‘;//标记作用,将这个点替换成碉堡 dfs( step+1 , num+1 );//向着下一个点前进 a[x][y]=‘.‘;//变回空地,为了回溯时候可以恢复岔路口的初始状态 } dfs( step+1 , num );//不管上面的这句if条件满不满足,都要进入下一句的判断 } int main(void) { int i, j, count; while ( scanf("%d", &len) , len ) { for ( i=1 ; i<=len ; i++ ) { getchar(); for ( j=1 ; j<=len ; j++ ) { scanf("%c", &a[i][j] ); } //getchar(); getchar不能放这里,会导致第一个字符会是回车(刚输完数字时) } /*输入测试for ( i=1 ; i<=len ; i++ ) { for ( j=1 ; j<=len ; j++ ) { printf("%c", a[i][j] ); } }*/ Count=0; dfs(0,0); cout<<Count<<endl; } return 0; }
以上是关于2018.07.29(搜索)学习DFS算法小记的主要内容,如果未能解决你的问题,请参考以下文章