萌新打卡 蓝桥杯 算法提高 经典题的简化版 递归实现(dfs)简易素数环 原题来自poj1016

首先声明,本文讨论的题素数环并不是poj1016那道十分经典的题,而是那一题的简化版本,也可以说是入门版。

Description

有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环。为了简便起见,我们规定每个素数环都从1开始。

例如,这就是6的一个素数环:1 4 3 2 5 6

Input

有多组测试数据,每组输入一个n(0<n<20)。

Output

每次输出一个整数,代表满足条件的素数环的总数。如果测试数据不存在素数环,则输出”No answer!”。

题解

比较那一经典题可以发现,此题并不要求输出所有情况而是只要求统计即可,于是问题就变得十分 简单起来。但是作为一个萌新的我刚拿到这个问题也是感觉一头雾水十分迷茫。
首先我们需要理清的一个问题是它的输入输出条件,依题意要判断一个数前后的值自然要想到把它们放在数组中更易于操作,所以开一个数组x[]存放这个生成的环,之后考虑输出,显然当统计总数为0时即不存在素数环故输出No answer!,另一种易于被忽略的情况是输入的数就是1,自然不存在素数环。并且在输出sum以后,由于是多组数据,记得将sum清零。因而我们可以写出主函数:

int main(){
	while(scanf("%d",&n)!=EOF){
       for(int i=1;i<=n;i++){//为了方便理解,数组从1开始的噢!
           x[i]=i;
       }
       f(2);
       if(sum==0||n==1){
           printf("No answer!");
       }
       else
            printf("%d",sum);
            sum=0;
	}
	return 0;
}

其次我们考虑递归函数,用到深搜的模板,首先考虑边界条件,当传入的数大于输入的n时,统计数加一,结束循环。(没写完全!!!往下看!)
那么考虑搜索部分了,从读入的数到末尾挨个遍历,然后设置一个swap来保证各种排列都能被涉及到,之后判断是否满足当前数和前一个数的和是一个质数,所以自然为了方便,我们还需要定义一个函数来判断是否为质数,好了,在判断完后,如果是质数,继续向下搜索另一种可能,如果不是,就通过交换回两个数返回(用回溯的思想)。这样看来似乎漏了一种情况,环末尾数并不一定能和环的头串起来,所以在开头(上一段)我们漏写了一种判断情况,出口应该还要加上一种情况那就是环末的数加上x[1]要是一个素数。
至此就完成了dfs函数的部分,质数判断函数相信不需要过多的说明,用bool函数来写是最简单不过了的。

完整代码如下

#include <bits/stdc++.h>
using namespace std;
int x[101];
int sum=0;
int n;
bool  Is_prime(int m){
	for(int i=2;i*i<=m;i++){
		if(m%i==0){
			return false;
		}
	}
	return true;
} 
void f(int s){
	if(s>n){
		if(Is_prime(x[n]+x[1])){
			sum++;
		}
	}
	else {
		for(int i=s;i<=n;i++){
			swap(x[s],x[i]);
			if(Is_prime(x[s-1]+x[s])){
				f(s+1);
			}
			swap(x[s],x[i]);
		}
	}
}
int main(){
	while(scanf("%d",&n)!=EOF){
       for(int i=1;i<=n;i++){
           x[i]=i;
       }
       f(2);
       if(sum==0||n==1){
           printf("No answer!");
       }
       else
            printf("%d",sum);
            sum=0;
	}
	return 0;
}

没了!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值