素数环解题

    《算法竞赛入门经典》这本书确实内容很丰富,但是对于初学者真的不怎么友善。主要的原因在于省略了太多的细节。为什么会有这样的情况呢?我个人是这样理解的,大多数人在给别人介绍一个知识点或者事物的时候,很容易将那些自己觉得比较简单或者基础的东西给省略掉。这种情况不是主观的,潜意识里就这么完成了。例如,我给一个人说,你看这瓶溶液是棕黄色的,至少不是硫酸铜。这里就有一个背景,硫酸铜溶液是蓝色的,我们为什么省略掉这个细节呢?因为我们潜意识里认为,别人也知道,而事实可能并非如此。回到这本书上来,有太多的内容也是专业。我最开始直接看后面的章节,真的很难看懂,又回头来逐章阅读,这种情况就好多了。

    在回溯算法里7-4这一节的例题,素数环一题目就省了很多的内容。这里给出一版本可以编译运行的代码,希望可以帮到有需要的朋友。实现了两种计数方式,一种从index为0开始,一种从index为1开始。大家可以注意区别。

0基数的方案

 1 #include <iostream>
 2 #include <string>
 3 
 4 #define max_num 33
 5 
 6 int isprime[max_num];
 7 int visit[max_num]; // if a data has been visited
 8 // assume that valid indices: 0,1,2,...,31, starting from 0
 9 int arr[max_num]; // store the data
10 int n;
11 
12 void build_isprime(int t_n)
13 {
14     if (t_n > max_num)
15     {
16         std::cout << "max_error:" << t_n << std::endl;
17         std::exit(-1);
18     }
19     // init n
20     n = t_n;
21     // init isprime
22     isprime[0] = 0; 
23     isprime[1] = 0;
24     isprime[2] = 1;
25     for (int i=3;i<max_num;i++)
26     {
27         bool flag = false;
28         for (int j = 2; j < i; j++)
29         {
30             if (i % j == 0)
31             {
32                 flag = true;
33                 isprime[i] = 0;
34             }
35         }
36         if (!flag)
37         {
38             isprime[i] = 1;
39         }
40     }
41     // init visit and arr
42     for (int i = 0; i < max_num; i++)
43     {
44         visit[i] = 0;
45         arr[i] = 0;
46     }
47     visit[1] = 1; // number 1 has been visited, not index 1 has been visited
48     arr[0] = 1;
49 }
50 
51 void dfs(int curr)
52 {
53     if (curr == n) // end condition, n is the index, not the number to deal
54     {
55         int sum_of_last_and_first = arr[0] + arr[n-1];
56         if (isprime[sum_of_last_and_first] == 1)
57         {
58             for (int i=0;i<n;i++)
59             {
60                 std::cout << arr[i] << " ";
61             }
62             std::cout << std::endl;
63         }
64     }
65     else // loop condition
66     {
67         for (int i=2;i<=n;i++) // i denotes the number we have to deal, not index
68         {
69             if (visit[i] == 0 && isprime[arr[curr-1] + i] == 1)
70             {
71                 arr[curr] = i;
72                 visit[i] = 1;
73                 dfs(curr+1);
74                 visit[i] = 0;
75             }
76         }
77     }
78 }
79 
80 int main()
81 {
82     build_isprime(6);
83     dfs(1);
84     return 0;
85 }

 

1基数的方案

 1 #include <iostream>
 2 #include <string>
 3 
 4 #define max_num 33
 5 
 6 int isprime[max_num];
 7 int visit[max_num]; // if a data has been visited
 8 // assume that valid indices: 1,2,3,...,32, starting from 1
 9 int arr[max_num]; // store the data
10 int n;
11 
12 void build_isprime(int t_n)
13 {
14     if (t_n > max_num)
15     {
16         std::cout << "max_error:" << t_n << std::endl;
17         std::exit(-1);
18     }
19     // init n
20     n = t_n;
21     // init isprime
22     isprime[0] = 0; 
23     isprime[1] = 0;
24     isprime[2] = 1;
25     for (int i=3;i<max_num;i++)
26     {
27         bool flag = false;
28         for (int j = 2; j < i; j++)
29         {
30             if (i % j == 0)
31             {
32                 flag = true;
33                 isprime[i] = 0;
34             }
35         }
36         if (!flag)
37         {
38             isprime[i] = 1;
39         }
40     }
41     // init visit and arr
42     for (int i = 0; i < max_num; i++)
43     {
44         visit[i] = 0;
45         arr[i] = 0;
46     }
47     visit[1] = 1; // number 1 has been visited, not index 1 has been visited
48     arr[1] = 1;
49 }
50 
51 void dfs(int curr)
52 {
53     if (curr == n+1) // end condition, n is the index, not the number to deal
54     {
55         int sum_of_last_and_first = arr[1] + arr[n];
56         if (isprime[sum_of_last_and_first] == 1)
57         {
58             for (int i=1;i<=n;i++)
59             {
60                 std::cout << arr[i] << " ";
61             }
62             std::cout << std::endl;
63         }
64     }
65     else // loop condition
66     {
67         for (int i=2;i<=n;i++) // i denotes the number we have to deal, not index
68         {
69             if (visit[i] == 0 && isprime[arr[curr-1] + i] == 1)
70             {
71                 arr[curr] = i;
72                 visit[i] = 1;
73                 dfs(curr+1);
74                 visit[i] = 0;
75             }
76         }
77     }
78 }
79 
80 int main()
81 {
82     build_isprime(6);
83     dfs(2);
84     return 0;
85 }

 

完结。

 

posted @ 2019-06-23 18:14  warnet  阅读(259)  评论(0编辑  收藏  举报