zoukankan      html  css  js  c++  java
  • 素数环解题

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

        在回溯算法里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 }

    完结。

  • 相关阅读:
    JavaScript与C# Windows应用程序交互
    用DateTime.ToString(string format)输出不同格式的日期
    时间间隔与暂停
    C#中比较两个时间的时间差
    lambda函数的用法
    Tornado笔记
    DjangoWeb应用开发实战笔记
    再看装饰器
    描述符
    flask简单代码回顾
  • 原文地址:https://www.cnblogs.com/warnet/p/11073625.html
Copyright © 2011-2022 走看看