• HDU1016 Prime Ring Problem (回溯 + 剪枝)


    本文链接:http://www.cnblogs.com/Ash-ly/p/5398684.html

    题意:

      给你一个数字N(N <= 20),要求你把这N个数组成一个环,环内的数字不能重复,左右相邻的两个的和是素数。给出最后的答案。

    思路:

      利用回溯剪枝算法,N个数,每个数有N种状态,枚举这N个状态,枚举过程中剪枝优化。

    代码:

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <cstring>
     5 #include <cmath>
     6 #include <cstdlib>
     7 #include <algorithm>
     8 using namespace std;
     9 
    10 const int MAXN = 43;
    11 int n;
    12 //素数表
    13 int isprime[MAXN] = {0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0};
    14 //判断是否重复
    15 int used[MAXN];
    16 
    17 //素数环
    18 int circle[MAXN];
    19 
    20 //判断 第 key 个位置的数字是否合法
    21 int check(int key)
    22 {
    23     if( used[ circle[key] ] ) //之前被用过
    24         return 0;
    25     if(!isprime[ circle[key] + circle[key - 1] ])//和前面一个组成了非素数
    26         return 0;
    27     if(key == n && !isprime[ circle[key] + 1 ])//最后一个数和第一个数的和也不能是素数
    28         return 0;
    29     return 1;
    30 }
    31 
    32 void backtrack(int key)
    33 {
    34     if(key > n)//回溯完毕 打印结果
    35     {
    36         for(int i = 1; i <= n; i++)
    37             cout <<(i == 1? "" : " ") << circle[i];
    38         cout <<endl;
    39     }
    40     else
    41     {
    42         for(int i = 2; i <= n; i++) //这个位置一共有 n - 1 个状态,分别枚举
    43         {
    44             circle[key] = i;
    45             if( check( key ) )      //剪枝处理
    46             {
    47                 used[i] = 1;        //标记这个点已被用
    48                 backtrack(key + 1);    
    49                 used[i] = 0;        //恢复现场
    50             }
    51         }
    52     }
    53 }
    54 
    55 int main()
    56 {
    57     int kas = 1;
    58     while(cin >> n)
    59     {
    60         printf("Case %d:
    ", kas++);
    61         memset(used, 0, sizeof(used));
    62         memset(circle, 0, sizeof(circle));
    63         circle[1] = 1;    //第一个数字从 1 开始
    64         backtrack(2); //从第二个数字开始求解
    65         cout << endl;
    66     }
    67     return 0;
    68 }
  • 相关阅读:
    Dapr6 Dapr 服务调用构建块
    Dapr6: Dapr 状态管理构建块
    06 IdentityServer4 中支持外部标识提供器
    RabbitMQ, Windows Server 上服务总线的替代品
    实战案例:Flink1.3.1 ON Hudi0.10,同步数据到Hive
    Flink 自定义触发器实现带超时时间的 CountWindow
    stackoverflow:What is LDAP used for?
    PriorityQueue使用介绍
    How to remove leading zeros from alphanumeric text?
    Java Regular Expression Remove Leading Zeros Example
  • 原文地址:https://www.cnblogs.com/Ash-ly/p/5398684.html
Copyright © 2020-2023  润新知