素数环(nyoj488)

素数环

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述

有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环。

为了简便起见,我们规定每个素数环都从1开始。例如,下图就是6的一个素数环。

输入
有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束。
输出
每组第一行输出对应的Case序号,从1开始。
如果存在满足题意叙述的素数环,从小到大输出。
否则输出No Answer。
样例输入
6
8
3
0
样例输出
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
Case 3:
No Answer



代码

#include<stdio.h>
#include<string.h>
#include<math.h>

int n = 0;
int a[20];
int b[20];
int count = 1;

int isprime(int m)
{
	int len, i;
	if(m < 3)
		return 0;	
	len = (int)sqrt(m + 0.0);
	for(i = 2; i <= len; i++)
	{
		if(m % i == 0)
			return 0;
	}
	return 1;

}

void back(int cur)
{
	int i, flag = 0;
//	p = count;
	if(cur == n && isprime(a[0] + a[n - 1]))                          //递归结束的条件
	{
//		printf("Case %d:\n", count++);
		for(int i = 0; i < n; i++)
		{
			printf("%d ", a[i]);
		}
		printf("\n");//flag = 1;
		return;
	}
//	if(!flag && cur == n){printf("Case %d:\n", count++);printf("No Answer\n");}
	else
		for(i = 2; i <= n; i++)
		{
			if(!b[i] && isprime(i + a[cur - 1]))
			{
				a[cur] = i;
				b[i] = 1;
				back(cur + 1);
				b[i] =  0;                                       //回溯时重新标记已经用过的数字为0
			}
		}
}

int main()
{
	int i;
	for(i = 0; i< 20; i++)
		a[i] = i + 1;
	memset(b, 0, sizeof(b));
	while(scanf("%d", &n) && n)
	{
		if(n == 1)
		{
			printf("Case %d:\n", count++);
			printf("1\n");
		}
		else 
		{
			if(n %2 )								//当n为奇数时不可能形成素数环  (两个奇数相加一定为偶数)
			{
				printf("Case %d:\n", count++);
				printf("No Answer\n");
				continue;
			}
			printf("Case %d:\n", count++);	
			back(1);                              //回溯时第一个数字为1
		}		
	}
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值