题意:
给你数字n ,求的一个1~n 的数字环,使得任意相邻的数的和为素数! 打印所有解。
思路:
直接素数打表判断素数,回溯法暴力每一个位置的每一个数即可。
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <unordered_map>
using namespace std;
unordered_map<string,bool>mp;
int vis[100];
void init(){
int len = sqrt(100+0.5);
for (int i = 2; i <= len; ++i) if (!vis[i])
for (int j = i*i; j <= 100; j += i) vis[j] = 1;
}
int a[100], n, vis2[100];
void dfs(int c){
if (c == n) {
int m = 100, p;
for (int i = 0; i < n; ++i){
if (a[i] < m) m=a[i], p = i;
}
string t = "";
for (int i = 0; i < n; ++i){
t += a[(i+p)%n] + 48;
}
if (!mp.count(t)){
for (int i = 0; i < n; ++i) {
if (i)printf(" ");
printf("%d",a[i]);
}
puts("");
mp[t] = true;
}
return;
}
for (int i = 1; i <= n; ++i){
if (!vis2[i]){
a[c] = i;
if (c == 0 || !vis[a[c] + a[(c-1+n)%n]] ){
if (c == n-1){
if (!vis[a[0] + a[n-1]]){
vis2[i] = 1;
dfs(c+1);
vis2[i] = 0;
}
continue;
}
else {
vis2[i] = 1;
dfs(c+1);
vis2[i] = 0;
}
}
}
}
}
int main(){
init();
int ks = 0;
while(~scanf("%d",&n)){
mp.clear();
memset(vis2,0,sizeof vis2);
if (ks)puts("");
printf("Case %d:\n",++ks);
dfs(0);
}
return 0;
}