洛谷-UVA524 素数环 Prime Ring Problem

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

题意:
输入正整数n,把整数1,2,…,n组成一个环,使得相邻两个整数之和均为素数。输出时,从整数1开始逆时针排列。同一个环恰好输出一次。n<=16.

多组数据,读入到EOF结束。

第i组数据输出前加上一行Case i:

相邻两组数据中间加上一个空行。

输入输出样例
输入 #1 复制
6
8
输出 #1 复制
Case 1:
1 4 3 2 5 6
1 6 5 2 3 4

Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2


思路:排序总数达到16!=2*10^13,利用回溯求解。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int is_prime(int x){ //判断素数
	for(int i = 2 ; i*i <= x; i++)
	if(x % i == 0) return 0;
	return 1;
} 
/*int is_prime(int x){ //判断素数
	int i = 2;
	while(i*i <= x && x % i != 0)
	i++;
	return i * i  > x;
} */

int n, a[50] , isp[50],vis[50];
void dfs(int cur){
	if(cur == n && isp[a[0]+a[n-1]]){//头尾数据相加
		for(int i = 0; i < n; i++){
			if(i != 0) printf(" ");
			printf("%d",a[i]);
		}
		printf("\n"); 
	}
	else for( int i = 2; i <= n; i++)
	if(!vis[i] && isp[i+a[cur-1]])//如果i没用过,并且与前一个数之和为素数
	{
		a[cur] = i;//尝试放i
		vis[i] = 1;
		dfs(cur+1);
		vis[i] = 0;//恢复现场标识
	 } 
}

int main(){
	int kase = 0;
	while(scanf("%d",&n) == 1 && n > 0){
		if(kase > 0) 
		printf("\n");
		printf("Case %d:\n", ++kase);
		for(int i = 2;i <= n*2 ;i++)//生成素数表,加快后续判断
		isp[i] = is_prime(i);
		memset(vis, 0, sizeof(vis));//初始化标识
		a[0] = 1;//第一个数1开始
		dfs(1);//深搜
	}
	
	return 0;
}
发布了430 篇原创文章 · 获赞 2 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/zqhf123/article/details/105405937
今日推荐