HDU 1016 Prime Ring Problem (DFS回溯)

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. 

 

Inputn (0 < n < 20). 
OutputThe 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
题解:
  
一般的DFS问题,需要使用回溯法,不然会超时。
代码如下:
#include<iostream>
#include<cstring>
using namespace std;
bool isp[50],vis[20];
int n,a[20];
bool is_prime(int n)
{
    for(int i=2;i*i<=n;i++)
        if(n%i==0)
            return false;
    return n!=1;
}
void dfs(int cur)
{
    if(cur==n&&isp[a[0]+a[n-1]])
    {
        for(int i=0;i<n-1;i++)
            printf("%d ",a[i]);
        printf("%d\n",a[n-1]);
    }
    else
        for(int i=2;i<=n;i++)//放置第i个数
        {
            if(!vis[i]&&isp[i+a[cur-1]])
            {
                a[cur]=i;
                vis[i]=true;
                dfs(cur+1);
                vis[i]=false;//回溯后对标记进行复原
            }
        }
}
int main()
{
    memset(isp,false,sizeof(isp));
    for(int i=2;i<2*20;i++)
        isp[i]=is_prime(i);//生成素数表
    a[0]=1;
    int cas=1;
    while(cin>>n)
    {
        memset(vis,false,sizeof(vis));
        printf("Case %d:\n",cas++);
        dfs(1);
        printf("\n");
    }
    return 0;
}

 

 
posted @ 2017-08-08 10:27  Zireael  阅读(147)  评论(0编辑  收藏  举报