Discription
输入正整数n,把整数1,2…,n组成一个环,使得相邻两个整数之和均为素数。输出时从整数1开始逆时针排列。同一个环应恰好输出一次。
Input
n (0 < n ≤ 16)
Output
如实例输出,注意中间有空行,最后一行没有空行
Sample Input
6
8
Sample Output
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
Solution
直接DFS枚举会T,对相邻两个加和不是素数的直接剪枝。
Code
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;
int n, m;
int num[20];
bool idx[20];
int kase = 1;
bool isPrime(int number)
{
for (int i = 2; i * i <= number; i++)
if (number % i == 0)
return false;
return true;
}
void solve()
{
for (int i = 0; i < n; i++)
printf("%d%c", num[i], i == n - 1 ? '\n' : ' ');
}
void dfs(int n_, int m_)
{
if (m_ == m + 1 && isPrime(num[0] + num[n - 1]))
{
solve();
return;
}
for (int x = 2; x <= n; x++)
{
if (idx[x] == false && isPrime(x + num[m_ - 1]))
{
idx[x] = true;
num[m_] = x;
dfs(x, m_ + 1);
idx[x] = false;
}
}
}
void init()
{
for (int i = 1; i <= n; i++)
idx[i] = false;
num[0] = 1;
}
int main()
{
// freopen("in.txt", "r", stdin);
bool tmp = false;
while (~scanf("%d", &n))
{
m = n - 1;
init();
if (tmp)
printf("\n");
tmp = true;
printf("Case %d:\n", kase++);
dfs(0, 1);
}
return 0;
}