就是说,给你一个数n,
要你把1到n都连在一起成环。
每一个数不可反复,
且相连的两个数的和要是素数。
把全部情况输出来。
我是用dfs暴力出来的。
首先把素数打表,
然后每次顺时针预測下一个数,
由于这个数必需要是素数减去上一个数,
非常好枚举。
我的代码例如以下:
#include<iostream> #include<cstring> #include<cstdlib> using namespace std; int map[30],num,prime[]={2,3,5,7,11,13,17,19,23,29,31,37,41},used[30],save[10000][30],cnt; void init() { cnt=0; memset(used,0,sizeof(used)); used[1]=1; map[1]=1; } int cmp(const void *a,const void *b) { return *(int *)a - *(int *)b; } bool isprime(int x) { int *p; p=(int *)bsearch(&x,prime,13,sizeof(int),cmp); if(p!=NULL) return 1; return 0; } void dfs(int i) { if(i==num) { if(isprime(map[num]+1)) { memcpy(save[cnt],map,sizeof(save[cnt])); cnt++; } return; } for(int j=0;j<13;j++) { int tmp=prime[j]-map[i]; if(tmp>num) break; if(tmp>1&&!used[tmp]) { map[i+1]=tmp; used[tmp]=1; dfs(i+1); used[tmp]=0; } } } int main() { int exp=0; while(scanf("%d",&num)!=EOF) { printf("Case %d: ",++exp); init(); dfs(1); for(int i=0;i<cnt;i++) { printf("%d",save[i][1]); for(int j=2;j<=num;j++) printf(" %d",save[i][j]); printf(" "); } printf(" "); } }