题意:给定一个整数,求其满足起点为1的素数环,,并把所有的素数环输出来。
类型:dfs+回溯
思路:因为起点为1,所以每次都从1开始进行深度优先搜索,设置一个数组ring,用来存放素数环的路径,当找到素数环的时候就打印环的路径。其中有一个剪枝的操作,如果给定的整数为奇数,那么肯定不存在素数环,(因为肯定存在两个奇数相邻,而奇数与奇数的和为偶数,所以一定不是素数环)所以不用进行搜索。做题的时候忘记写输入的数据以EOF结束,导致出现了Output Limit Exceeded这种错误。
时间复杂度:最坏的时间复杂度为O((n-1)!);
#include <iostream>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
int visit[30];//标记已被访问的数
int ring[30];//存储环路径
int n;//节点个数
//判断是否是素数
bool isPrime (int a){
int f=1;
if(a==2){
return f;
}
for(int i=2;i*i<=a;i++){
if(a%i==0){
f=0;
break;
}
}
return f;
}
//dfs
void dfs(int i){
if(i==n&&isPrime(ring[n]+1)){//满足条件 则返回
//打印路径
for(int j=1;j<=n;j++){
cout<<ring[j]<<" ";
}
cout<<endl;
return ;
}
for(int j=2;j<=n;j++){
if(!visit[j]&&isPrime(ring[i]+j)){//没有被访问 并且与上次节点和为素数
visit[j] = 1;//标记被访问
ring[i+1] = j;
dfs(i+1);
visit[j] = 0;//回溯后 将节点置为未被访问 下次要用
}
}
}
int main() {
cin>>n;
for(int i=1;i<=n;i++){//置所有节点未被访问
visit[i] = 0;
}
ring[1] = 1;//固定 1 为路径第一个数
if(n%2!=0){//如果是奇数 无解
cout<<-1;
return 0;
}
dfs(1);
return 0;
}