One point optimization of dfs backtracking algorithm for prime number ring

description

 有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻的两个数(包括首和尾)的和都为素数,称为素数环。为了简便起见,我们规定每个素数环都从1开始。例如,6的一个素数环:
 1 4 3 2 5 6
 请编写一个程序,给定一个输入n(0<n<20),如果存在满足要求的素数环,从小到大输出。否则,输出No Answer。

  I used dfs plus the backtracking method to do this question. The backtracking process is also very simple. I will definitely talk about it in other blogs, but I think there is a trick in the dfs process. I think it is very good. Share it here:
  First of all Define an array

int Next_prime[1001];//Next_prime[i]表示大于i的最小的质数

  Then initialize it in the main function

    {
        int j = 1;
        int pri = prime[j];// prime[i]代表第i个质数
        for(int i = 1; i < 501; i++)
        {
            if(i >= pri)
            {
                j ++;
                pri = prime[j];
            }
            Next_prime[i] = pri;
        }
    }

  Then when it is not in the last position in dfs

    {
        int prenum = round[po - 1];/*round[i]代表环上第i个数是多少,po为dfs中当前环上第po个位置,prenum代表前环上前一个数字*/
        int ne = Next_prime[prenum];
        int d = ne - prenum;/*尝环将环后一个数字更改为d,ne一定是个质数*/
        while(d <= n )//n是环的长度
        {
            if(d > 0 && !is_used[d])
            {
                round[po] = d;
                is_used[d] = 1;
                dfs(po + 1);//尝试下一个位置的值
                is_used[d] = 0;//回溯
            }
            ne = Next_prime[ne];
            d = ne - prenum;/*下一次尝试时只需要ne = Next_prime[ne],保证ne仍是质数而且d增大了 */
        }
    }

  The advantage of this is that it reduces the number of times to determine whether it is a prime number. Of course, this trick cannot change the fact that the data of the prime number ring itself grows exponentially. It can only slightly simplify the calculation.
  In addition, when n is an odd number, there must be no prime number ring. This is due to the drawer principle. There must be two non-one odd numbers adjacent to each other, and the sum will be an even number. If this is not considered, ac may not be possible.

Attachment: Number of prime number rings Gx <script type="math/tex" id="MathJax-Element-34">G(x) </script>
G ( 2 ) = 1 , G ( 4 ) = 2 , G ( 6 ) = 2 , G ( 8 ) = 4 , G ( 10 ) = 96 , G ( 12 ) = 1024 , G ( 14 ) = 2880 , <script type="math/tex" id="MathJax-Element-35">G(2) = 1, G(4) = 2, G(6) = 2, G(8) = 4, G(10) = 96, G(12) = 1024, G(14) = 2880, </script>
G ( 16 ) = 81024 , G ( 18 ) = 770144 , G ( 20 ) = 6309300 , G ( 22 ) = 213812336 <script type="math/tex" id="MathJax-Element-36">G(16) = 81024, G(18) = 770144, G(20) = 6309300, G(22) = 213812336. . . </script> It
can be seen that as the number grows, this trick is not very useful...

Guess you like

Origin blog.csdn.net/zhongershuchong/article/details/78923471