HDU1016--Prime number ring problem

HDU1016-prime number ring problem

1. Topic link

HDU1016

2. Subject content

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.
Insert picture description here

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

translation

The ring consists of n circles, as shown in the figure. Put the natural numbers 1, 2,..., n into each circle respectively, and the sum of the numbers in two adjacent circles should be prime numbers.
Note: The number of the first circle should always be 1.
The output format is shown below. Each row represents a series of circle numbers starting from clockwise and counterclockwise 1 in the ring. The sequence of numbers must meet the above requirements. Print solutions in lexicographic order.
You will write a program to complete the above process.
In each case, a blank line is printed.

Three, the question is disassembled

The topic this time is very concise and clear.

Put the natural numbers 1, 2,..., n into each circle respectively, and the sum of the numbers in two adjacent circles should be prime numbers.
Note: The start of the circle should always be 1.

This sentence tells us three pieces of information:

  1. The numbers from 1 to n should be arranged in a ring connected end to end, that is, the first number and the last number are connected.
  2. The sum of any two adjacent numbers must be a prime number.
  3. All output numbers should start with 1.

OK, then we will start solving the problem directly.

Four, problem-solving ideas

First of all, the question requires that the sum of any two adjacent numbers is a prime number, and it must be combined into a ring and use up all the numbers.
So what was our first reaction? Put the numbers after 1 into the queue one by one to see if it can form a prime number with the previous number. If it can, update the series, if not, switch to the next number and put it in. After updating the sequence, re-stuff the sequence in from the beginning until the length of the sequence is equal to n or some numbers cannot be inserted.
Let's look at an example.
For example, we enter

6

At this time, we initialize the queue first, and the queue is

1

Then let's see if 2 can be packed behind 1, 1+2=3 is a prime number, you can plug it in, update the queue

1 2

Then see if 3 can be inserted, 2+3=5 is a prime number, insert it, update the queue

1 2 3

Then see if 4 can be inserted, 3+4=7 is a prime number, insert it, update the queue

1 2 3 4

And so on, 5 + 4 = 9 is not a prime number, to view the next
64 = 10 is not prime +, but at this time has no next number can go stuffed, prove that this sort does not work, then we fall back on a digital
this When the queue goes back to

1 2 3

Because 4 would lead to subsequent columns can not be perfect, we will continue to look at a number
35 = 8 is not prime +, the next
3 + 6 = 9 is not a prime number, but later they did not figure it out, we continue to go back to a queue
this When the queue goes back to

1 2

Then repeat this behavior, we can find the first queue that meets the meaning of the question

1 4 3 2 5 6

Then we output it and continue to find the next one.
This is the specific idea of ​​this question. So how to achieve it?
Because we may have to go back to the queue of the previous step, how we save the queue of the previous step is very important. Those who have studied data structures should know that there is such a concept in C++-stack. This is exactly what we need to save.
So we use the stack to save, so what method is to use the stack in the data structure?
Yes, it is recursion, so we use recursion to write this question.
After solving the storage problem, the next step is to judge the problem.
Because we need to judge a prime number every time we add and subtract, we'd better write the judgment prime number as a function for us to call.
However, calling the function will also take up a lot of computing time, so we can mark the prime numbers in advance, that is, make a table of prime numbers.
We create an array, because the maximum title n is 20, so we can create an array of 41, initialize it to 0, and then mark the non-prime number as 1. I will have detailed comments in the code for the specific table.
After solving these big problems, the next step is to pay attention to the details of the problem.
First of all: the topic is a multiple data input, and each data input needs the corresponding order label. For
example, the first set of data we want to output

Case 1:

The second point to pay attention to is that every time the data finds all feasible queues, a blank line must be output.
The third point is also a point that I have always ignored. After each column of data is output, there should be no extra spaces.
The above is the specific solution and main points of this problem.

Five, reference code

//
// Created by Verber.
//
#include "iostream"
#include "bits/stdc++.h"
#include "queue"
using namespace std;
int n;
int biao[42],zu[22],pd[22];//三个数组分别储存的是素数表,数列,以及判断该数字是否入队
void sushudabiao()//打表函数
{
    
    
    memset(biao,0,sizeof(biao));//初始化数组
    for (int i = 2; i<= 42; i++)
    {
    
    
        if(biao[i]==0)//如果是素数,它的倍数一定不是素数
        {
    
    
            for(int t=i*2;t<=42;t+=i)
            {
    
    
                biao[t]=1;
            }
        }
    }

}
void zhaohuan(int num)//递归函数
{
    
    
    if (num == n && biao[zu[0] + zu[n - 1]]==0)//当递归层数等于n时并且首尾数相加是素数的情况下跳出递归,输出数列
    {
    
    
        for (int i = 0; i <n-1; i++)
        {
    
    
            cout<<zu[i]<<" ";
        }
        cout<<zu[n-1]<<endl;//最后一个数字后面不能有多余的空格
        return;
    }
    else
    {
    
    
        for (int j = 2; j <= n; j++)//循环去寻找下一个塞进去数列的数字
        {
    
    
            if (!pd[j] && biao[j + zu[num - 1]]==0)
            {
    
    
                zu[num] = j;//把该数字入列
                pd[j] = 1;//表示该数字已入列
                zhaohuan(num + 1);//如果该数字能塞到当前数列后面,重新查找下一个数字
                pd[j] = 0;//当执行完上一步的递归后,无论能否成数列,都要让该数字出列,查找新的能塞到当前位置的数字,找新的数列。
            }
        }
    }
}
int main()
{
    
    
    sushudabiao();
    int i=1;
    while (scanf("%d",&n)!=EOF) {
    
    
        cout<<"Case "<<i++<<":"<<endl;
        zu[0] = 1;
        memset(pd,0,sizeof(pd));//每一步初始化判断列表。可省略
        zhaohuan(1);
        cout<<endl;

    }
}

Guess you like

Origin blog.csdn.net/Verber/article/details/113101714