hdu1016

/*此题是一个典型的引用dfs的题细节颇多很有意思可能是博主之前刚学习完的缘故这道题若用素数打表会超时但是博主没有试高效打表法,直接用判断素数函数就好。此题思路是深搜每两个相邻的和是素数加一些边界判断想通了简单 一定要思路清楚不局限于作此题这个思路很相同*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#define maxx 1000000+10

using namespace std;

int n;
int visit[21], a[21];//a环中的数字,visit访问的标记
int prime[maxx];//素数表
/*void init_prime()//简单素数打表
{
    int i, j;
    for(i = 2;i <= sqrt(1000002.0); ++i)
    {
        if(!prime[i])
            for(j = i * i; j < 1000002; j += i)
                prime[j] = 1;
    }
    j = 1;
    for(i = 1;i <= 1000002; ++i)
        if(!prime[i])
            prime[j++] = 1;
        else prime[j++] = 0;
}
*/
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)
{
    visit[a[x]] = 1;//②上一步处理此时的节点加下一个几点的和用的是a[x]+i的方法所以这里将每传入的这个节点置为1则自动向该节点的下一个节点扫描
    if(x == n && is_prime(a[x]+a[1])){
        for(int i = 1; i < n; i++)
            printf("%d ", a[i]);
        printf("%d\n", a[n]);//这一步的操作是为了不在最后一组数据后面当上空格而已

    }
    else{
        for(int i = 1; i <= n ; i++){
            if(!visit[i] && is_prime(a[x]+i)){//①首先想到的是判断前一个暑假后一个数是否为素数且不能重复将以前扫过的节点再次扫描
                a[x+1] = i;//③这是通过遍历的方法进行的确定的路径所以每次遍历的i是路径中的元素因为之前遍历过的都已置为1这保证了结果的准确
                dfs(x+1);//④给当前节点赋值后将该节点传值以为我们的思想永远是将接受的节点与下一个节点的和来判断是否为素数
                visit[i] = 0;//⑤这一步不能忽略很重要的,若上一个节点回溯的话,那么上上一个节点就需要与上一个节点的下一个节点进行判断这一步便是将上一个节点的下一个节点置为未访问过
            }
        }
    }
}

int main()
{
    int cnt = 0;
    while(scanf("%d", &n) != EOF){
        memset(visit, 0, sizeof(visit));
       //memset(prime, 0, sizeof(prime));//这里不能忘了
       //init_prime();
        printf("Case %d:\n", ++cnt);//这里一定要注意别把格式写错了
        a[1] = 1;
        dfs(1);
        printf("\n");
    }
    return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值