NYOJ 488 -素数环(DFS)

题目链接 http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=488

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

【输入格式】
有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束。

【输出格式】
每组第一行输出对应的Case序号,从1开始。
如果存在满足题意叙述的素数环,从小到大输出。
否则输出No Answer

【思路】
DFS枚举全排列,注意当n>1且n为奇数时是无解的,需要直接特判

#include<bits/stdc++.h>
using namespace std;

const int maxn=25;

int n,flag;
int a[maxn];
bool notp[maxn<<1];

void init(){
	for(int i=2;i<(maxn<<1);++i){
		if(!notp[i]) for(int j=i*2;j<(maxn<<1);j+=i) notp[j]=true;
	}
}

void dfs(int cur){
	if(cur==n){
		if(!notp[a[0]+a[n-1]]){
			flag=1;
			for(int i=0;i<n;++i) printf("%d%c",a[i],i+1==n?'\n':' ');
		}
		return;
	}
	for(int i=2;i<=n;++i){
		bool ok=true;
		for(int j=0;j<cur;++j){
			if(a[j]==i){
				ok=false;
				break;
			}
		}
		if(ok && !notp[i+a[cur-1]]){
			a[cur]=i;
			dfs(cur+1);
		}
	}
}

int main(){
	init();
	int kase=0;
	while(scanf("%d",&n)==1 && n){
		printf("Case %d:\n",++kase);
		if(n>1 && (n&1==1)){
			puts("No Answer");
			continue;
		}
		a[0]=1;
		flag=0;
		dfs(1);
		if(!flag) puts("No Answer");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/xiao_k666/article/details/82875251