hdu 1016

Prime Ring Problem

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 19792    Accepted Submission(s): 8850


Problem Description
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.

 
Input
n (0 < n < 20).
 
Output
The 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
 
思路:运用深搜的算法,从1到n进行搜索。
方法一:

#include<string.h>
int visit[20],a[20];
int is_prime(int x)//判断是否是素数
{
    int i;
    for(i=2;i*i<=x;i++)
    if(x%i==0)
    return 0;
    return 1;
}
void DFS(int count ,int num,int n)//count是计数的,num代表当前的数字
{
    int i;
    a[count]=num;                 //把num赋值给a[count],储存在数组中
    visit[num]=1;                 //把访问过的数字做标记
    if(count==n&&is_prime(a[count]+a[1]))      //当满足条件的数的数量达到n时,判断最后一个数与第一个数的和是否是素数
    {
            printf("1");
            for(i=2;i<=n;i++)
            printf(" %d",a[i]);
            printf(" ");
    }
    for(i=1;i<=n;i++)
    {
        if(visit[i]==0&&is_prime(a[count]+i))//如果条件成立,则进行递归。
        {
            DFS(count+1,i,n);
            visit[i]=0;//一定要回溯到0
        }
    }
}
int main()
{
    int k=1,n;
    while(~scanf("%d",&n))
    {
        printf("Case %d: ",k++);
        memset(visit,0,sizeof(visit));
        DFS(1,1,n);
        printf(" ");
    }
}


方法二:

#include<stdio.h>
#include<string.h>
int n,a[20],visit[20];//a[]数组用来储存符合条件的数据
int is_prime(int y)//素数判断
{
 int j;
 for(j=2;j*j<=y;j++)
  if(y%j==0)
   return 0;
   return 1;
}
void DFS(int x)//x用来作为a[]数组的下标
{
 int i;
 visit[a[x]]=1;//把每个要访问的数都标记为1
 if(x==n&&is_prime(a[x]+a[1]))//下标x==n的时候进行判断最后一个数与第一个数的和是否是素数
 {
          for(i=1;i<n;i++)
   printf("%d ",a[i]);
    printf("%d ",a[i]);
 }
 for(i=1;i<=n;i++)
 {
  if(visit[i]==0&&is_prime(a[x]+i))//找符合条件的数
  {
   a[x+1]=i;
   DFS(x+1);
   visit[i]=0;
  }
 }
}
int main()
{
 int t=0;
 while(scanf("%d",&n)!=EOF&&(n>0&&n<20))
 {
     a[1]=1;
  printf("Case %d: ",++t);
  memset(visit,0,sizeof(visit));
  DFS(1);
  printf(" ");
 }
 return 0;
}

原文地址:https://www.cnblogs.com/lxm940130740/p/3268111.html