【HDU】1016 Prime Ring Problem(DFS)

49 篇文章 0 订阅
26 篇文章 0 订阅
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
 
 
68
 
Sample Output
 
 
Case 1:1 4 3 2 5 61 6 5 2 3 4Case 2:1 2 3 8 5 6 7 41 2 5 8 3 4 7 61 4 7 6 5 8 3 21 6 7 4 3 8 5 2


    这道题是非常典型的一道DFS搜索的应用,在代码注释中已经把基本思路写的很详细了。

AC代码:

//
//  main.cpp
//  1016
//
//  Created by showlo on 2018/4/11.
//  Copyright © 2018年 showlo. All rights reserved.
//

#include <stdio.h>
int n,a[25],vis[25];

//int prime[40]={0,1,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 prime(int n){               //判断是不是素数的函数
    int i;
    for (i=2; i<n; i++) {
        if (n%i==0) {
            return 0;
        }
    }
    return 1;
}

void dfs(int i)             //dfs搜索符合条件的
{
    if (i==n&&prime(a[i-1]+a[0])) {         //如果搜索到了第n+1个数,且第n个数与a[0]的和是素数,则是满足题意的一种方案
        for(int j=0;j<i-1;j++)
            printf("%d ",a[j]);
        printf("%d\n",a[i-1]);
    }                                       //这里要注意输出格式
    else{                                   //如果还没有搜索完n个数,继续搜索
        for (int j=2; j<=n; j++) {          //由于a[0]=1已经确定,所以只需要从2开始搜索
            if (vis[j]==0) {                //如果这个数之前没有被访问过,继续判断是否符合要求(与a[i-1]的和是否为素数)
                if (prime(a[i-1]+j)==1) {    //如果是素数
                    vis[j]=1;               //标记这个数为被访问过
                    a[i++]=j;               //用于储存输出结果的数组中第i+1个数设置为j
                    //i++;
                    dfs(i);                  //继续搜索i+1
                    vis[j]=0;                //这一趟搜索完之后,在判断下一个j是否满足之前,要把这个vis[j]初始为0
                    i--;                    //还原i
                }
            }
        }
    }
}



int main() {
    int i;
    int kase;
    kase=0;
    while (scanf("%d",&n)!=EOF) {
        kase++;
        printf("Case %d:\n",kase);
        for (i=1; i<=20; i++) {
            vis[i]=0;
        }
        a[0]=1;
        dfs(1);
        printf("\n");
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值