[HDU] 1016 Prime Ring Problem

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=1016

方法:建立好状态树,状态树中的每一个节点有4个变量,即

        1,当前状态为构造最终目标状态使用了什么数字的数组,后文称usedNums。

        2,当前状态为构造最终目标状态还可以使用的数字的数组,后文称avaliableNums。

        3,当前状态为构造最终目标状态已经构造了多大的长度,也就是该状态节点在树中的层数,后文称layer。

        4,目标状态的长度。

每一个状态节点使用当前所在层数-1作为下标,取出已经构造好了的usedNums的最后一个数字x。然后枚举当前avaliableNums的数字y,看能不能和x相加得到素数,如果能,则其子状态节点的usedNums为其usedNums加上y,avaliableNums为其avaliableNums去掉y.然后从其子节点开始深搜。

如果当前状态节点所有的avaliableNums都枚举完毕都不能再找到能和x相加得到素数的y,搜索就此停止,该搜索路径不能达到目标状态。

否则一直搜索到目标状态所在那一层,再判断最后一个数和第一个数相加能不能得到素数。能就说明是个满足要求的素数环,输出,否则收索失败,直接返回。

感想:再构造子状态节点的时候,可以把当前状态的usedNums和avaliableNums先统一地复制给各个子状态节点,然后在搜索的时候分别更新各自的usedNums和avaliableNums。这样效率高点,而不是在从每个子节点开始深搜的时候,分别为每个子节点复制下当前的usedNums和avaliableNums,然后再跟新。

代码:

View Code
#include<iostream>
using namespace std;
int n;
bool isPrime[] = {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, 0};
int g_source[20] = {0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20} ;
int g_target[20] = {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} ;
void DFSSearch(int source[20], int layerNo, int target[20])
{
    if(layerNo == n-1)
    {
        if(isPrime[target[layerNo]+1])
        {
            for(int i = 0;i<n;i++)
            {
                printf("%d",target[i]);
                if(i<n-1)
                    printf(" ");
                else
                    printf("\n");
            }
        }
        return;
    }
    else
    {
        int t_source[20],t_target[20];
        for(int i = 0;i<n;i++)
        {
            t_source[i]=source[i]; 
            t_target[i]=target[i];
        }
        for(int i = 0;i<n;i++)
        {
            if(source[i]!=0)
            {
                if(isPrime[source[i]+target[layerNo]])
                {
                    t_source[i]=0;
                    t_target[layerNo+1] = source[i];
                    DFSSearch(t_source,layerNo+1,t_target);
                    t_source[i]=source[i];
                }
            }
        }

    }
}
int main()
{
    int i=1;
    while(scanf("%d",&n)!=EOF)
    { 
        printf("Case %d:\n",i);
        DFSSearch(g_source,0,g_target);
        printf("\n");
        i++;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/kbyd/p/3022081.html