Prime Ring Problem HDU - 1016(回溯法)

本题用回溯法即可,下面有两个版本,

版本1

#include <stdio.h>
#include <string.h>

bool mark[21];  //mark[i]用于标记i+1是否被填充 
int list[20];
int n;    //总共的个数 

int prime[] = {3,5,7,11,13,17,19,23,29,31,37};

//判断新插入的元素和前一个元素的和是否是素数 
//注意,这里x表示下标,值的范围是从[1,n-1] 
bool judge(int x)   
{
    int tmp = list[x] + list[(x-1)%n];
    bool flag = false;
    for(int i = 0; i < 11; i++)
        if(tmp == prime[i])
        {
            flag = true;
            break;
        }
    return flag;
}

//用于判断list[0]和list[n-1] 
bool judgeSE()
{
    int tmp = list[0] + list[n-1];
    bool flag = false;
    for(int i = 0; i < 11; i++)
        if(tmp == prime[i])
        {
            flag = true;
            break;
        }
    return flag;
}

void print()
{
    for(int i = 0; i < n; i++)
    {
        if(i == 0)
            printf("%d", list[i]);
        else
            printf(" %d", list[i]);
    }
    printf("\n");
}

//x表示下标,当前正在填充list[x] 
void DFS(int x)
{
    //判断第一个和最后一个数是否满足条件 
    if(x == n && judgeSE())
    {
        print();
        return;
    }
        
    //将2和n之间的数填进list[x]中 
    for(int i = 2; i <= n; i++)
    {
        if(mark[i])   //如果i已经被填充 
            continue;
        list[x] = i;    //试探i填进list[x] 
        if(judge(x))     //判断list[x]和list[x-1]是否满足条件
        {
            mark[i] = true;
            DFS(x+1);
            mark[i] = false;
        } 
    }
}

int main()
{
    int num = 1;
    while(~scanf("%d", &n))
    {
        memset(mark, 0, sizeof(mark));
        list[0] = 1;
        mark[0] = true;
        printf("Case %d:\n", num++); 
        DFS(1);
        printf("\n");
    }    
    return 0;    

版本2

#include <stdio.h>
#include <string.h>

bool mark[21];  //mark[i]用于标记i是否被填充 
int list[21];
int n;    //总共的个数 

int prime[] = {3,5,7,11,13,17,19,23,29,31,37};

bool judge(int x)   
{
    for(int i = 0; i < 11; i++)
        if(x == prime[i])
            return true;
    return false;
}

void print()
{
    for(int i = 1; i <= n; i++)
    {
        if(i == 1)
            printf("%d", list[i]);
        else
            printf(" %d", list[i]);
    }
    printf("\n");
}

//x表示下标,当前正在填充list[x] 
void DFS(int x)
{
    //判断第一个和最后一个数是否满足条件 
    if(x == n+1 && judge(list[x-1] + list[1]))
    {
        print();
        return;
    }
        
    //将2和n之间的数填进list[x]中 
    for(int i = 2; i <= n; i++)
    {
        if(mark[i])   //如果i已经被填充 
            continue;
        list[x] = i;    //试探i填进list[x] 
        if(judge(list[x] + list[x-1]))     //判断list[x]和list[x-1]是否满足条件
        {
            mark[i] = true;
            DFS(x+1);
            mark[i] = false;
        } 
    }
}

int main()
{
    int num = 1;
    while(~scanf("%d", &n))
    {
        memset(mark, 0, sizeof(mark));
        list[1] = 1;
        mark[1] = true;
        printf("Case %d:\n", num++); 
        DFS(2);
        printf("\n");
    }    
    return 0;    

猜你喜欢

转载自blog.csdn.net/mch2869253130/article/details/86093650
今日推荐