深搜,主要是搜索状态的确定与转移。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1016
通过题目发现的问题:1、对深搜确定一个搜索状态还不太清楚。2、实现一个算法还比较慢,以后要勤加练习!
小结:深搜其实是一种盲目搜索,是利用计算机高效计算性能从而找到结果的一种方法!
正确的CODE:
2 #include<stdlib.h>
3 #include<string.h>
4 #include<assert.h>
5 #include<math.h>
6 #define MAX_LEN 11
7
8
9 int flag[MAX_LEN + 10];
10 int num[MAX_LEN + 10];
11 int n;
12
13
14 int is_prime(int n)
15 {
16 int i , m;
17 assert(n >= 0);
18 if(n == 1) return 0;
19 m = floor (sqrt (n) + 0.5);
20
21 for(i = 2; i <= m ;i++)
22 {
23 if(n%i == 0) return 0;
24 }
25 return 1;
26 }
27
28
29
30 void dfs(int index) //深度优先搜索
31 {
32 if(index == n) //index是一种状态。由它来控制搜索的结束状态
33 {
34 if(is_prime (num[index - 1] + 1))
35 {
36 for(int i = 0;i < n ;i++) //总共循环的次数
37 {
38 printf(i!=n-1?"%d ":"%d\n" , num[i]);
39 }
40 }
41 return ;
42 }
43
44 for(int i = 2; i <= n;i++) //从2开始一直加到n
45 {
46 if(!flag[i] && is_prime(num[index - 1] + i))
47 {
48 flag[i] = 1;
49 num[index] = i;
50 dfs (index + 1);
51
52 flag[i]=0; //回溯
53 }
54 }
55 }
56
57
58
59 int main()
60 {
61 int cases = 0;
62 while(~scanf("%d", &n))
63 {
64 printf("Case %d:\n", ++cases);
65
66 memset(flag , 0 , sizeof(flag));
67
68 num[0] = 1;
69 dfs(1);
70 printf("\n");
71 }
72 return 0;
73 }
顺便贴下错误的代码:
2 #include<string.h>
3 #include<stdio.h>
4 #include<assert.h>
5 #include<math.h>
6
7 const int maxn = 21;
8 int num[maxn];
9 int flag[maxn];
10 int n;
11
12 int is_prime(int x)
13 {
14 if(x == 1) return 0;
15 assert(x >= 0);
16 int m = floor(sqrt(x) + 0.5);
17 for(int i = 2; i <= m ; i++)
18 if(x%i==0)
19 return 0;
20 return 1;
21 }
22
23
24 void dfs(int i)
25 {
26 int j ;
27 if(i == n) //状态量
28 {
29 if(is_prime(1 + num[i-1]))
30 {
31 for(i = 0 ;i < n ; i++)
32 {
33 printf(i!=n-1? "%d ":"%d\n", num[i]);
34 }
35 }
36 return ;
37 }
38
39 for(j = 2 ;j <= n ; j++)
40 {
41 if(is_prime(num[i-1] + j) && !flag[j])
42 {
43 num[i] = j;
44 flag[j] = 1;
45 dfs(i + 1);
46 flag[j] = 0; //回溯
47 }
48 }
49 }
50
51
52 int main()
53 {
54 int n; //局域变量覆盖了全局变量,不只一次犯这错误啦,泪奔。。。。
55 int times = 0;
56 while(~scanf("%d", &n))
57 {
58 int i ;
59 memset(num , 0 ,sizeof(num));
60 memset(flag, 0 ,sizeof(flag));
61
62 num[0] = 1;
63 printf("Case %d:\n", ++times);
64 dfs(1);
65 printf("\n");
66 }
67 return 0;
68 }