杭电1016 素环问题

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

                素环问题

        时间限制:4000/2000 MS MS(Java / Others)内存限制:65536/32768 K
问题描述
  环由n个圆组成,如图所示。将自然数1,2,…,n分别放入每个圆中,两个相邻圆中的数字之和应为素数。
  注意:第一个圆的数量应始终为1。
  
输入
   n(0 <n <20)。
  
输出
  输出格式如下所示。每行代表环中的一系列圆圈数,从1开始顺时针和逆时针开始。数字的顺序必须满足上述要求。按字典顺序打印解决方案。
  您将编写一个完成上述过程的程序。
  每个案例后打印一个空行。
  
样本输入

6
8

样本输出

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、素环,说白了就是数列的一种特殊排列方式。所以,只要你求出该数列的全排列,那就能得到所有的素环情况。但是当数列的元素个数很多时,求其全排列必然会浪费很多的时间…
  2、因为起点为1,所以每次都从1开始进行深度优先搜索,设置一个数组b,用来存放素数环的路径,当找到素数环的时候就打印环的路径。
  
代码示例


#include<stdio.h>//素数环---递归实现1016
int b[100];
int N,i;
int su(int a)                     //素数判定函数
{
    int j,n=0;
    if(a==1) return 0;
    for(j=2;j<a;j++)
    {
       if(a%j==0)
       n++;
    }
    if(n==0)//是素数
       return 1;
    else
       return 0;
}
void huan(int a[])                //递归实现深搜
{
    int k,j,n;
    if(i==N-1&&su(b[i]+b[0]))     //找到一条素数环
    {
        for(k=0;k<N;k++)
        {
           if(k==0)
              printf("%d",b[k]);
           else
              printf(" %d",b[k]);
        }
        printf("\n");
    }
    else
    {
        for(k=1;k<N;k++)
        {
            n=1;
            for(j=0;j<=i;j++)
            {
               if(a[k]==b[j])
               n=0;
            }
            if(n==0)
               continue;
            if(su(b[i]+a[k]))      //找到一个数与数组b的最后一个数和为素数,就将其存入数组b,并进入深一层的递归
            {
                i++;
                b[i]=a[k];
                huan(a);
                i--;               //数组b的回溯
            }
        }
    }
}
int main()
{
    int m=0;
    int a[100];
    while(~scanf("%d",&N))
    {
        m++;
        for(i=0;i<N;i++)
        {
            a[i]=i+1;
        }
        b[0]=1;
        i=0;
        printf("Case %d:\n",m);
        huan(a);
       printf("\n");
    }
    return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值