Prime Ring Problem(经典的搜索题目)

Prime Ring Problem(经典的搜索题目)

Prime Ring Problem

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 5409    Accepted Submission(s): 2402


Problem Description
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.

Prime Ring Problem(经典的搜索题目)_第1张图片
 

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
 

Source
Asia 1996, Shanghai (Mainland China)
 
搜索
 1 #include < iostream >
 2 using   namespace  std;
 3 // 在50以内的素数堆
 4 int  prim[ 50 ] = { 0 , 0 , 2 , 3 , 0 , 5 , 0 , 7 , 0 , 0 , 0 , 11 , 0 , 13 , 0 , 0 , 0 , 17 , 0 , 19 , 0 , 0 , 0 , 23 , 0 , 0 , 0 , 0 , 0 , 29 , 0 , 31 , 0 , 0 , 0 , 0 , 0 , 37 , 0 , 0 } ; // 由于范围是在n (0 < n < 20).所以最大的是19+20=39
 5 int  n,t;
 6 int  pre_num[ 21 ]; // 用来保存要输出的数组
 7 bool  used[ 21 ]; // 记录是否这个用到数字
 8
 9 void  dfs( int  v, int  num) // num记录的map数组的满足条件的个数,V是当前的一点
10 {
11      int  i;
12      if (num == n) // 结尾的条件num==n,还要测试是否是环
13      {
14          if (prim[v + 1 ] != 0 ) // 是素数,形成一个素数环
15          {
16             cout << " 1 " ;
17              for (i = 2 ;i < t;i ++ )
18                 cout << "   " << pre_num[i]; // 就是先打一个空格再打数字可以避免最后多余的空格
19             cout << endl;    
20         }

21          return  ;
22     }

23      else
24      {
25          for (i = 2 ;i <= n;i ++ )
26          {
27              if ( used[i] == false   &&  prim[i + v] != 0  ) // 没有记录在内并且满足条件(是素数)
28              {
29                 used[i] = true ; // 先标记过
30
31                 pre_num[t ++ ] = i; // 再添加到数组中
32
33                 dfs(i,num + 1 ); // 递归的两个参数一个代表满足和前面一个数相加为素数的条件,后面一个为num
34                 
35                 used[i] = false ; // 回溯,搜索的关键
36             
37                 t -- ; // 回溯的时候数组num要减1
38             }

39
40         }

41         
42     }

43     
44 }

45 int  main()
46 {
47      int  cas = 1 ;
48      while (cin >> n)
49      {
50         cout << " Case  " << cas ++<< " : " << endl;
51         memset(used, 0 , sizeof (used));
52
53         used[ 1 ] = true ; // 开始永远是1,Note: the number of first circle should always be 1.
54         t = 1 ;
55         pre_num[t ++ ] = 1 ; // t是记录数组中暂时的个数
56
57         dfs( 1 , 1 ); // 从1开始
58         cout << endl; // 最后还有一个大换行    
59     }

60     
61      return   0 ;
62 }

63

你可能感兴趣的:(Prime Ring Problem(经典的搜索题目))