The 20 numbers 1, 2,... and 20 are arranged in a row, so that the sum of the two adjacent numbers is a prime number, and the first and last two digits are also a prime number.

Three methods are provided:

(Note: In order to make the program faster, according to the characteristics of the arrangement, each method has fixed the last element. In this way, the output is only part of the condition, but you can modify the output of each method, all elements are output by moving a position, such as 123. The first output is 123, 2nd, 231, and 3rd, so that all the solutions can be obtained .)

The following is a brief description of the brute force method.

Idea of brute-force method: arrange 1-n all, and then check each order to see whether the conditions and outputs are met.

Recursion only sorts data. The idea of recursion is to choose one from 1 to n to the last position, and (recursion) select one from the remaining number to the next position, and then **, follow this loop.

By the way, this method is very slow. After completing all the arrangement, it will take several hundred million recursion times. You have to wait a long time (maybe several hours, haha) to see the result. However, you can replace the for statement I have commented on with the for statement below to quickly see the result.

For more information, see the explanation in the code.

If you understand the brute force method, you can understand method 3. You don't need to read it. You may not understand it. Although the speed is the three faster ones, it is more difficult to understand.

If you don't understand it, it's your problem. Maybe you don't know what the arrangement is, or you don't know what the recursion is. (You should read this book instead of simply asking .)

# Include <stdio. h>

# Include <malloc. h>

# Include <memory. h>

# Include <math. h>

# Include <time. h>

Bool IsPrimeNumber (int n)

{/* Determine the prime number */

Int I;

Int sqrootN;

If (n = 2 ){

Return true;

} Else if (n % 2 = 0 | n = 1 ){

Return false;

}

SqrootN = (int) (sqrt (n) + 0.1) + 1;

I = 3;

While (I <sqrootN ){

If (n % I = 0 ){

Return false;

}

I + = 2;

}

Return true;

}

Void Swap (int * a, int * B)

{/* Swap two numbers */

Int tmp;

Tmp = *;

* A = * B;

* B = tmp;

}

Bool IsOk (int * arr, int arrsize)

{/* Determine whether conditions are met */

If (! IsPrimeNumber (arr [arrsize-1] + arr [0]) {

Return false;

}

While (-- arrsize> 0 ){

If (! IsPrimeNumber (arr [arrsize] + arr [arrsize-1]) {

Return false;

}

}

Return true;

}

//////////////////////////////////////// ////////////////

// Method 1:

Bool Adjust_Pair (int * arr, int arrsize, int depth)

{

Static int total = 0;

Bool ret = false;

Int I;

If (depth = 2 ){

If (IsPrimeNumber (arr [0] + arr [arrsize-1]) {

Total ++;

Printf ("\ n % 03d:", total );

For (I = 0; I <arrsize; I + = 2 ){

Printf ("% 02d-% 02d", arr [I], arr [I + 1]);

}

Return true;

} Else {

Return false;

}

}

For (I = depth-2; I> 1; I-= 2 ){

If (IsPrimeNumber (arr [I-1] + arr [depth-2]) {

Swap (arr + depth-3, arr + i-1 );

Swap (arr + depth-4, arr + I-2 );

If (Adjust_Pair (arr, arrsize, depth-2 )){

Ret = true;

}

Swap (arr + depth-3, arr + i-1 );

Swap (arr + depth-4, arr + I-2 );

}

}

Return ret;

}

Bool Make_Pair (int * arr, int arrsize, int depth)

{

Bool ret = false;

Int I;

Static int total1 = 0;

Static int total2 = 0;

If (depth = 0 ){

Return Adjust_Pair (arr, arrsize, arrsize );

}

For (I = 0; I <depth-1; I + = 2 ){

If (IsPrimeNumber (arr [depth-1] + arr [I]) {

Swap (arr + depth-2, arr + I );

If (Make_Pair (arr, arrsize, depth-2 )){

Ret = true;

}

Swap (arr + depth-2, arr + I );

}

}

Return ret;

}

Void DoPermutation (int * arr, int arrsize)

{

If (arrsize % 2 = 1 ){

Printf ("\ n result: nonexistent (the array size must be an even number ).");

Return;

}

If (! Make_Pair (arr, arrsize, arrsize )){

Printf ("\ n Result: No .");

}

}

//////////////////////////////////////// //////////////

// Brute force method: unconditionally arrange all rules and determine whether conditions are met one by one.

Bool _ DoPermutation2 (int * arr, int arrsize, int depth)

{

Static int total = 0;

Bool ret = false;

Int I;

If (depth = 0) {/* sorted */

If (IsOk (arr, arrsize) {/* determine whether the condition is met. if the condition is met, output */

Total ++;

Printf ("\ n % 03d:", total );

For (I = 0; I <arrsize; I + = 2 ){

Printf ("% 02d-% 02d", arr [I], arr [I + 1]);

}

Return true;

} Else {

Return false;

}

}

/* For (I = (depth + 1) % 2; I <depth; I + = 2) {changing the for below to this for can optimize the speed by half */

For (I = 0; I <depth; I ++) {/* depth-1 is equivalent to the last position of the array */

Swap (arr + depth-1, arr + I);/* select arr [I] to the last position in the array. arr [depth-1] */

If (_ DoPermutation2 (arr, arrsize, depth-1) {/* depth-1 element before recursive arrangement */

Ret = true;

}

Swap (arr + depth-1, arr + I);/* switch back to keep the original array unchanged */

}

Return ret;

}

Void DoPermutation2 (int * arr, int arrsize)

{

If (arrsize % 2 = 1 ){

Printf ("\ n result: nonexistent (the array size must be an even number ).");

Return;

}

If (! _ DoPermutation2 (arr, arrsize, arrsize-1 )){

Printf ("\ n Result: No .");

}

}

//////////////////////////////////////// //////////////

// Method 3: recursion is performed only when the ongoing arrangement meets some conditions.

Bool _ DoPermutation3 (int * arr, int arrsize, int depth)

{

Static int total = 0;

Bool ret = false;

Int I;

If (depth = 0 ){

If (IsPrimeNumber (arr [arrsize-1] + arr [0]) {

Total ++;

Printf ("\ n % 03d:", total );

For (I = 0; I <arrsize; I + = 2 ){

Printf ("% 02d-% 02d", arr [I], arr [I + 1]);

}

Return true;

} Else {

Return false;

}

}

For (I = (depth + 1) % 2; I <depth; I + = 2 ){

/* For (I = 0; I <depth; I ++) {You can replace the preceding statement with one, but the preceding statement is better */

If (! IsPrimeNumber (arr [depth] + arr [I]) {

Continue;

}

Swap (arr + depth-1, arr + I );

If (_ DoPermutation3 (arr, arrsize, depth-1 )){

Ret = true;

}

Swap (arr + depth-1, arr + I );

}

Return ret;

}

Void DoPermutation3 (int * arr, int arrsize)

{

If (arrsize % 2 = 1 ){

Printf ("\ n result: nonexistent (the array size must be an even number ).");

Return;

}

If (! _ DoPermutation3 (arr, arrsize, arrsize-1 )){

Printf ("\ n Result: No .");

}

}

Int main (int argc, char * argv [])

{

Clock_t start, finish;

Int arr [100], I;

For (I = 0; I <100; I ++ ){

Arr [I] = I + 1;

}

/* Method 1 */

DoPermutation (arr, 18 );

/* Brute Force Method */

/* DoPermutation2 (arr, 18 );*/

/* Method 3 */

/* DoPermutation3 (arr, 18 );*/

Return 0;

}