现在的位置: 首页 > 综合 > 正文

hdoj 1016 Prime Ring Problem 深搜回溯

2019年11月21日 ⁄ 综合 ⁄ 共 924字 ⁄ 字号 评论关闭

一道很入门的深搜回溯题http://acm.hdu.edu.cn/showproblem.php?pid=1016

没有优化剪枝,执行时间较长,但可以ac

#include <iostream>
#include <math.h>
using namespace std;
int n,id=0; //n为输入,id为输出的case编号
int depth = 0; //记录递归的层数,每一层对应填入的一个值的位置
int solution[21]; //解数组,因为1已经填入,因此保存除了1之外的数字的顺序,下标从0开始
int used[21]; //记录元素是否已经使用过了,下标从1开始到n对应n个元素

//判断一个数是否为素数
bool isPrime(int num)
{
    for(int i=2 ; i<=sqrt(num) ; ++i)
    {
        if(num % i == 0)
        {
            return false;
        }
    }
    return true;
}
//深搜回溯,依次填入 2到n
void PrimeRing(int curr )
{
    if(depth == n-1 && isPrime(curr+1)) //终止条件,若已经填入了n-1个数字(1认为已经填入了) 且最后一个与1相加素数
    {
        cout << "1";  //从1开始,1第一个输出
        for(int i=0 ; i<n-1 ; ++i)  //输出结果
        {
            cout << " " << solution[i];
        }
        cout << endl;
        return ;
    }
    for(int i=2 ; i<=n ; ++i)
    {
        if(used[i]==0 && isPrime(curr + i)) //若i没被使用,且和为素数
        {
            solution[depth] = i;
            depth++;       //深度增加1
            used[i] = 1;   //使用状态置1
            PrimeRing(i); //深搜
            used[i] = 0;   //回溯后使用状态为0;
            depth--;    //回溯后深度减少1
        }
    }
    return ;
}
int main()
{
    while(cin >> n)
    {
        for(int i=0 ; i<=n ; ++i) //初始化使用状态数组
            used[i] = 0;
        used[1] = 1; //从1开始,1肯定被使用
        cout << "Case " << ++id << ":" << endl;
        PrimeRing(1);
        cout << endl;
    }
    return 0;
}

抱歉!评论已关闭.