AC日记—— codevs 1031 质数环(搜索)
题目描述 Description
一个大小为N(N<=17)的质数环是由1到N共N个自然数组成的一个数环,数环上每两个相邻的数字之和为质数。如下图是一个大小为6的质数环。为了方便描述,规定数环上的第一个数字总是1。如下图可用1 4 3 2 5 6来描述。若两个质数环,数字排列顺序相同则视为本质相同。现在要求你求出所有本质不同的数环。
输入描述 Input Description
只有一个数N,表示需求的质数环的大小。如:
输出描述 Output Description
每一行描述一个数环,如果有多组解,按照字典序从小到大输出。如:
样例输入 Sample Input
6
样例输出 Sample Output
1 4 3 2 5 6
1 6 5 2 3 4
数据范围及提示 Data Size & Hint
n<=17
思路:
搜索不解释
(每次判断是否与前一个数相加为质数,最后一个则和第一个判断)
来,上代码:
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n_,num_loop=0,thing[100][20],now_n_[20]; bool if_in_[20]; bool if_prime_(int N_) { int N_s = sqrt(N_); for(int i=2 ; i<=N_s ; i++) { if( N_ % i == 0) return false; } return true; } bool ok_to_(int thg_,int now_) { if(now_ == n_) { if(if_prime_(thg_ + now_n_[1])) { return true; } else return false; } else { if(if_prime_(thg_ + now_n_[now_ -1])) { return true; } else return false; } } void dfs_for_prime_loop(int now_) { if(now_ == n_ + 1) { bool ok_if_in_[100]; memset(ok_if_in_,false,sizeof(ok_if_in_)); for(int i=1;i<=n_;i++) { if(!ok_if_in_[now_n_[i]]) ok_if_in_[now_n_[i]]=true; else return ; } num_loop ++; for(int i=1 ; i<=n_ ; i++) { thing[num_loop][i]=now_n_[i]; } return ; } for(int i=2 ; i<=n_ ; i++) { if(if_in_[i]) continue ; if(!if_in_[i]) { if(ok_to_(i,now_)) { if_in_[i]= true; now_n_[now_]= i; dfs_for_prime_loop(now_ + 1); if_in_[i]= false; } } } } void put_(int now_) { if(now_ == 0) return ; else { put_(now_ / 10); putchar(now_%10 + 48); } } void Put_out_int_(int now_) { if(now_== 0) { putchar('0'); return ; } put_(now_ / 10); putchar(now_ % 10 + 48); } int main() { scanf("%d",&n_); if_in_[1]=true,now_n_[1]=1; dfs_for_prime_loop(2); for(int i=1 ; i<=num_loop ; i++) { putchar('1'); putchar(' '); for(int j=2 ; j<=n_ ; j++) { //putchar(thing[i][j] + 48); Put_out_int_(thing[i][j]); putchar(' '); } putchar('\n'); //for(int j=1 ; j<=n_ ; j++) printf("%d ",thing[i][j]); /*for(int j=1 ; j<=n_ ; j++) cout<<thing[i][j]<<" "; cout<<endl;*/ } return 0; }