题目链接:https://vjudge.net/problem/UVA-524
题意:输入正整数n,把1~n这n个整数组成一个环,使得相邻两个整数之和均为素数。输出时从1开始逆时针排序。同一个换应恰好输出一次。n<=16。
分析:粗略的计算一下,如果生成1~n的全排列暴力计算,排列总数最高达16!=2*10^13,很可能会超时,在此应用回溯法将会快很多。注意全局标记变量在调用完递归函数后要复原。
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=105;
int n;
int vis[maxn];
int ans[maxn];
bool is_prime(int sum){ //判断是否是素数
for(int i=2;i<=sqrt(sum);i++)
if(sum%i==0)
return false;
return true;
}
void dfs(int cur){
if(cur==n&&is_prime(ans[n-1]+1)) {
for(int i=0;i<n;i++){
printf("%d",ans[i]);
printf(i==n-1?"\n":" ");
}
}else{
for(int i=2;i<=n;i++){
if(!vis[i]&&is_prime(ans[cur-1]+i)){
ans[cur]=i;
vis[i]=1;//标记使用过的整数
dfs(cur+1);
vis[i]=0;//将标记变量改回来
}
}
}
return;
}
int main () {
//freopen("in.txt", "r", stdin);
int k=1,ok=0;
while(cin>>n){
if(ok) printf("\n");
ok=1;
memset(vis,0,sizeof(vis));
printf("Case %d:\n",k++);
ans[0]=1;//由于输出第一个值一定是1,所以直接赋值,搜索直接从2开始
dfs(1);
}
return 0;
}