## dfs---------------------深度优先搜索

深度优先搜索就是不断地重复深入的过程直到找到你需要结果或者越界为止

``````void dfs(int step)
{
判断边界
尝试每一种可能 for(i=1;i<=n;i++)
{
继续下一步 dfs(step+1);
}
返回
}``````

实现方法

DFS一般用递归来实现，改变当层状态不断深入，直到找到答案或者已经可以知道这样下去无法得到答案，再返回到上一个状态（恢复该层状态）继续递归。保证每一个点（每一种可能性）都遍历过，但是并不能保证答案是最优解（如最小值，最短路等，这些一般用BFS实现）。

如图，在这棵树上做dfs为 1 2 4 5 3 6 7

1.

## A - Oil Deposits

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<algorithm>
using namespace std;
int xy[8][2]={1,0,1,-1,1,1,0,1,0,-1,-1,0,-1,1,-1,-1}; //八个方向。
char s[110][110];
int ans,m,n;
void dfs(int x,int y){
s[x][y] = '*';             // 将@变为*
for(int i = 0;i < 8; i++){
int a = x + xy[i][0];
int b = y + xy[i][1];
if(a < m && a >= 0 && b < n && b >= 0 && s[a][b] == '@')
dfs(a,b);
}
return;
}
int main(){
while(cin >> m >> n && n && m){
ans = 0;
for(int  i = 0;i < m; i++)
scanf("%s",s[i]);
for(int i = 0; i < m;i++)
for(int j = 0; j < n;j++){//遍历每个点
if(s[i][j] == '@'){//判断该点是不是@，如果是的话，dfs。
dfs(i,j);
ans++;
}
}
cout << ans<<endl;
}
return 0;
}
``````

## D - Prime Ring Problem

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 <bits/stdc++.h>

using namespace std;
int n;
struct node
{
int mark;
int num;
}stu[25];
int prime[12]={2,3,5,7,11,13,17,19,23,29,31,37};

int  dfs(int k)
{
int flag;
int i;
if(k==n+1)
{
for(i=0;i<12;i++)
{
if((stu[k-1].num+1)==prime[i])
{
for(int j=1;j<n;j++)
printf("%d ",stu[j].num);
printf("%d\n",stu[n].num);
}
}

}
else
{
for(i=2;i<=n;i++)
{
flag=0;
for(int j=0;j<12;j++)
{
if((i+stu[k-1].num)==prime[j])
flag=1;
}
if(stu[i].mark&&flag)
{
stu[i].mark=0;
stu[k].num=i;
dfs(k+1);
stu[i].mark=1;
}
}

}
return 0;
}

int main()
{
int Case=1;
while(cin>>n)
{
printf("Case %d:\n",Case++);
if(n==1)
{
printf("1\n\n");
continue;
}

stu[1].mark=0;
for(int i=2;i<=n;i++)
stu[i].mark=1;
stu[1].num=1;
dfs(2);
printf("\n");

}
return 0;
}``````