素數環
- 描述
-
有一個整數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
-
/*************************************************************************
> File Name: PrimeRing.cpp
> Author: SSW
> Mail: [email protected]
> Created Time: Mon 28 Jul 2014 15:51:12 CST
************************************************************************/
#include<iostream>
#include<string.h>
#include<stdio.h>
#define N 25
using namespace std;
bool isp[2*N];
bool is_prime(int n){
if(n <= 1) return false;
for(int i = 2; i*i<=n; i++){
if(0==n%i)
return false;
}
return true;
}
void DFS(int n, int *vis, int *A, int cur, int &K, int &OK){
if(cur==n && isp[ A[0]+A[cur-1]]){//不要漏掉1和最後一個的和是否爲素數
//OK = 1;//沒有奇偶判斷時用來標記是否有素數環存在
for(int i=0; i<n; i++)
printf("%d ",A[i]);
printf("\n");
}
for(int i=2; i<=n; i++){
if(!vis[i] && isp[i+A[cur-1]]){
vis[i]=1;
A[cur]=i;
DFS(n, vis, A, cur+1, K, OK);
vis[i]=0;
}
}
}
int main(){
for(int i = 0; i < 2*N; i++ )
isp[i] = is_prime(i);
/*這裏可以用另一種素數篩選法————找那些不是素數的數,不是素數則標記爲1
//在這裏可以嘗試其他的素數篩選法
for(int i = 2; i < 10; i++)
if(!isp[i])
for(int j = 2*i; j < 50; j += i)
isp[j] = 1;
*/
int n, K=0;
while(~scanf("%d", &n)&&n){
int vis[N], A[N], cur, OK;
printf("Case %d:\n", ++K);
memset(vis, 0, sizeof(vis)); memset(A, 0 , sizeof(A));//memset函數的第二個參數要注意是int 型還是 char 型,第三個參數應該是///實際的長度
vis[1]=1; A[0]=1; cur =1; OK = 0;
if(1 == n) {
printf("1\n");
continue;
}
if(0 != n%2){ //在這裏有一個常識,也是做這個題時間方面要考慮的:只有奇數和偶數個數相等時才能形成素數環,如果不相等的話,勢必有兩個奇//數在一起這樣和就不是素數,所以只有偶數個才形成素數環(1除外,應爲2是特殊的素數)。沒有這個優化,在NYOJ運行會超時
printf("No Answer\n");
continue;
}
DFS(n, vis, A, cur, K, OK);
/*if(!OK){
printf("No Answer\n");
}*/
}
return 0;
}
/*在這裏進行了一下素數的測試,怕自己出錯
int main(){
for(int i = 0; i < 2*N; i++){
isp[i] = is_prime(i);
printf("isp[%d]=%d ",i, isp[i]);
}
return 0;
}
*/