DFS:
深搜相较于广搜就有点困难了,因为他是用递归实现的,凡事沾点递归就难了。别看他代码量比广搜小,但其的时间复杂度远比广搜大,因为广搜是用大量空间来减少时间,而深搜是用回溯法。但深搜又是走遍所有可行的路线,所有时间大大增加。但是你可以剪枝啊,这又是另一个专题了。算无止境。对于递归不要想得太明白,容易绕进去,知道他的作用就可以。
基本模板:
void dfs(int x)
{
if (x == n&&pirme(a[n] + a[1]))//搜到了终点便输出并返回
{
for (int i = 1; i<n; i++)
cout << a[i] << " ";
cout << a[n] << endl;
return;
}
else
{
for (int i = 2; i <= n; i++)//不是终点就发展下一个点
{
if (t[i] == 0 && pirme(i + a[x]))
{
a[x + 1] = i;
t[i] = 1;//标记为走过的点
dfs(x + 1);//从新的点搜下去
t[i] = 0;//关键步骤!!!取消标记
}
}
}
}
相关例题:
Oil Deposits
Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 21636 | Accepted: 11267 |
Description
The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rectangular region of land at a time, and creates a grid that divides the land into numerous square plots. It then analyzes each plot separately, using sensing equipment to determine whether or not the plot contains oil. A plot containing oil is called a pocket. If two pockets are adjacent, then they are part of the same oil deposit. Oil deposits can be quite large and may contain numerous pockets. Your job is to determine how many different oil deposits are contained in a grid.
Input
The input contains one or more grids. Each grid begins with a line containing m and n, the number of rows and columns in the grid, separated by a single space. If m = 0 it signals the end of the input; otherwise 1 <= m <= 100 and 1 <= n <= 100. Following this are m lines of n characters each (not counting the end-of-line characters). Each character corresponds to one plot, and is either `*', representing the absence of oil, or `@', representing an oil pocket.
Output
are adjacent horizontally, vertically, or diagonally. An oil deposit will not contain more than 100 pockets.
Sample Input
1 1 * 3 5 *@*@* **@** *@*@* 1 8 @@****@* 5 5 ****@ *@@*@ *@**@ @@@*@ @@**@ 0 0
Sample Output
0 1 2 2
题目大意:找油田,既不相邻的油田有几块,注意斜角也算连在一起的。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 105;
char mapp[MAX][MAX];
int n, m;
int dirstion[8][2] = { 1,-1,1,0,0,1,0,-1,-1,0,-1,1,-1,-1,1,1 };
void dfs(int x, int y)
{
mapp[x][y] = '*';
for (int i = 0; i<8; i++)
{
int a = x + dirstion[i][0];
int b = y + dirstion[i][1];
if (a >= 0 && a<n&&b >= 0 && b<m&&mapp[a][b] == '@')
{
dfs(a, b);
}
}
}
int main()
{
while (~scanf("%d %d", &n, &m) && n&&m)
{
int sum = 0;
for (int i = 0; i<n; i++)
{
for (int j = 0; j<m; j++)
cin >> mapp[i][j];
}
for (int i = 0; i<n; i++)
{
for (int j = 0; j<m; j++)
{
if (mapp[i][j] == '@')
{
dfs(i, j);
sum++;
}
}
}
cout << sum << endl;
}
return 0;
}
Prime Ring Problem
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 66006 Accepted Submission(s): 28270
Problem Description
A ring is compose of n circles as shown in diagram. Put natural number 1, 2, ..., n into each circle separately, and the sum of numbers in two adjacent circles should be a prime.
Note: the number of first circle should always be 1.
Input
n (0 < n < 20).
Output
The output format is shown as sample below. Each row represents a series of circle numbers in the ring beginning from 1 clockwisely and anticlockwisely. The order of numbers must satisfy the above requirements. Print solutions in lexicographical order.
You are to write a program that completes above process.
Print a blank line after each case.
Sample Input
6
8
Sample Output
Case 1:
1 4 3 2 5 6
1 6 5 2 3 4
Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2
题目大意:素数环,环上任意两个相邻的数加起来为素数。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX = 105;
char mapp[MAX][MAX];
int n, m;
int dirstion[8][2] = { 1,-1,1,0,0,1,0,-1,-1,0,-1,1,-1,-1,1,1 };
int t[21], a[21];
bool pirme(int x)//判断是否为素数
{
int i;
if (x == 1)
return false;
for (i = 2; i<x; i++)
{
if (x%i == 0)
break;
}
if (i >= x)
return true;
else
return false;
}
void dfs(int x)
{
if (x == n&&pirme(a[n] + a[1]))
{
for (int i = 1; i<n; i++)
cout << a[i] << " ";
cout << a[n] << endl;
return;
}
else
{
for (int i = 2; i <= n; i++)
{
if (t[i] == 0 && pirme(i + a[x]))
{
a[x + 1] = i;
t[i] = 1;
dfs(x + 1);
t[i] = 0;
}
}
}
}
int main()
{
int t1 = 0;
while (~scanf("%d", &n))
{
memset(t, 0, sizeof(t));
memset(a, 0, sizeof(a));
a[1] = 1;
// if(t1!=0) cout<<endl; //一定注意输出格式
t1++;
cout << "Case " << t1 << ":" << endl;
dfs(1);
cout << endl;
}
return 0;
}