DFS总结(持续更新)
1,DFS(深度优先搜索),由于使用递归的方法,所以其经常适用于数据范围较小的题目中;
2,有关DFS的问题,经常可以套用模板来做,模板下面给出。
1 void dfs(参数)
2 {
3 if(搜到了或达到了目的)//要有终止条件总之:check()/ judge()去判定
4 {
5 计数或进行其他操作;
6 return;
7 }
8 for(查找当前节点的周围的节点)不是一定使用for,总之就是根据题目进行*改变*
9 {
10 进行其他的操作;
11 标记已经搜索过的节点;
12 dfs(下一次搜索的节点);
13 取消标记; //进行回溯***
14 }
15 }
3,一些练习的题目
全排列
八皇后
1 #include<cstdio>
2 #include<iostream>
3 #define inf 0x3f3f3f3f
4 using namespace std;
5 const int maxn=105;//注意范围要足够大
6 int a[maxn], b[maxn],c[maxn],d[maxn];
7 int n,ans=0;
8 void print(){
9 ans++;
10 if(ans<=3)//保证输出三个解
11 {
12 for(int k=1; k<=n; k++)
13 cout << a[k] << " " ;
14 cout << endl ;
15 }
16 }
17 void dfs(int i){
18 if(i==n+1) //寻找完所有皇后输出其纵坐标
19 {
20 print();//自定义输出函数
21 return ;
22 }
23 else
24 {
25 for(int j=1; j<=n; j++)//寻找可放置位置
26 {
27 if(b[j]==0&&c[i+j]==0&&d[i-j+n]==0)// 是否符合条件
28 {
29 a[i]=j;//占领位置
30 b[j]=1;//占领纵列
31 c[i+j]=1;//占领对角线(左下-右上)
32 d[i-j+n]=1;//占领对角线(左上-右下)
33 dfs(i+1);//寻找下一个皇后坐标
34 b[j]=0;//回溯
35 c[i+j]=0;
36 d[i-j+n]=0;
37 }
38 }
39 }
40 return ;
41 }
42 int main(){
43 cin >> n ;
44 dfs(1);//从第一个皇后 开始寻找坐标
45 cout << ans ;//输出
46 return 0;
47 }
48 //八皇后问题 仅输出前三个解的坐标以及总共解的个数
主对角线坐标和相同,副对角线差值相同(八皇后中可能为负所以加了n)
The Pilots Brothers’ refrigerator
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 35108 Accepted: 13583 Special Judge
Description
The game “The Pilots Brothers: following the stripy elephant” has a quest where a player needs to open a refrigerator.
There are 16 handles on the refrigerator door. Every handle can be in one of two states: open or closed. The refrigerator is open only when all handles are open. The handles are represented as a matrix 4х4. You can change the state of a handle in any location [i, j] (1 ≤ i, j ≤ 4). However, this also changes states of all handles in row i and all handles in column j.
The task is to determine the minimum number of handle switching necessary to open the refrigerator.
Input
The input contains four lines. Each of the four lines contains four characters describing the initial state of appropriate handles. A symbol “+” means that the handle is in closed state, whereas the symbol “−” means “open”. At least one of the handles is initially closed.
Output
The first line of the input contains N – the minimum number of switching. The rest N lines describe switching sequence. Each of the lines contains a row number and a column number of the matrix separated by one or more spaces. If there are several solutions, you may give any one of them.
Sample Input
-+--
----
----
-+--
Sample Output
6
1 1
1 3
1 4
4 1
4 3
4 4
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<algorithm>
5 #define INF 0x3f3f3f3f
6 using namespace std;
7 char maps[10][10];
8 int mp[10][10];
9 int ans=INF, flag;
10 //int dx[] = {0, 1, -1, 2, -2, 3, -3};
11 //int dy[] = {0, 1, -1, 2, -2, 3, -3};
12 int row[20], col[20];
13 bool judge(){
14 for(int i = 1; i <= 4; i++)
15 for(int j = 1; j <= 4; j++)
16 {
17 if(mp[i][j] != 1) return false;
18 }
19 return true;
20 }
21
22 void flip(int row, int col)//翻转
23 {
24 //整行整列翻转
25 mp[row][col] = !mp[row][col];
26 for (int i = 1; i <= 4; i++)
27 {
28 mp[i][col] = !mp[i][col];
29 mp[row][i] = !mp[row][i];
30 }
31 }
32
33 void dfs(int x, int y, int turn){//理清行列的表达
34 if(judge())
35 {
36 ans = min(ans, turn);
37 // printf("%d\n", ans);
38 if(ans!=INF){
39 printf("%d\n",ans);
40 for(int i = 0; i < ans; i++)
41 cout<<row[i]<<" "<<col[i]<<endl;
42 }
43 else printf("Impossible\n");
44 return ;
45 }
46 if(x>=5||y>=5) return ;
47
48 // int nx = (x+1)%5;//
49 // int ny = y + (x+1)/5;
50 int nx, ny;
51 nx = (x+1)%5;
52 ny = y + (x+1)/5;
53 if(nx == 0) nx = 1;
54 dfs(nx, ny, turn);
55 flip(x, y);
56 row[turn] = x, col[turn] = y;/路径输出***
57 dfs(nx, ny, turn+1);
58 flip(x, y);
59 return ;
60 }
61 int main(){
62 for(int i = 1; i <= 4; i++)
63 for(int j = 1; j <= 4; j++)
64 {
65 cin >> maps[i][j];
66 mp[i][j] = (maps[i][j]=='-'?1:0);
67 }
68 dfs(1, 1, 0);
69 // if(ans!=INF){
70 // printf("%d\n",ans);
71 // for(int i = 0; i < ans; i++)
72 // cout<
73 // }
74 // else printf("Impossible\n");
75 return 0;
76 }
做这题期间做了诸多修改,应该多积累经验,以思考对于有关DFS的题目应如何处理,以及一些***细节***的处理;
比如本题是有关DFS的最短路径输出问题,细节上要注意如何表达行与列(row&col),如何进行转换,以及翻转开关。
在进行代码书写时要注意理清思路,以及适当作注释提醒。
传送门