1. 程式人生 > >素數環 (深搜)

素數環 (深搜)

描述

有一個整數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

思路:

輸入0退出,1和非偶數的可以構成素數環,看評論區出題人說1也可以構成,頭和尾都是1之和為2

程式碼:

#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std;
int a[45]={0},b[21]={0},v[21]={0},n;
void init()//篩選出素數 
{
	int i,j;
	for(i=2; i<45; i++)
		a[i] = i;  
	for (i=2; i*i<45; i++)
	{
		if (a[i] != 0)
		for (j=i*2; j<45; j+=i)
		{
			a[j] = 0;
		}
	}
}
void dfs(int x)
{
	int i,j;
	if (x > 0 && b[0]!=1)  //必須1開頭 
	{
		return ;
	}
	for (j=2; j<=x; j++)
	{
		if (!a[b[j-2]+b[j-1]]) //兩素數之和不是素數之間返回 
		{
			return ;
		}
	}
	if (x == n)//剛好n個數 ,是一種解 
	{
		if (a[b[0] + b[x-1]]) //頭和尾也必須是素數 
		{
			for (j=0; j<n; j++)
			{
				cout<<b[j]<<" "; 
			}
			cout<<endl;
			return ;	
		}
	}
	for (i=1; i<=n; i++)
	{
		if (!v[i])
		{
			b[x] = i;
			v[i] = 1;
			dfs(x+1); //列舉第二個數 
			v[i] = 0;
		}
	}
} 
int main()
{
	init();
	int i,j,ca=1,T=0;
	while (cin>>n)
	{
		if (n==0)
			break;
		T++;
		cout<<"Case "<<T<<":"<<endl;
		memset(v,0,sizeof(v));
		if (n==1)
		{
			cout<<1<<endl;
		}
		else if (n%2==0)
		{
			dfs(0);
		}
		else
		{
			cout<<"No Answer"<<endl;
		}
	}
	return 0;
 }