『P1549』棋盘问题
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,f[15][15]; 4 bool prime[205],use[105]; 5 bool check(int x) { 6 for(int i=2;i<=sqrt(x);i++) 7 if(x % i==0) return 0; 8 return 1; 9 } 10 void print() { 11 for(int i=1;i<=n;i++){ 12 for(int j=1;j<n;j++) 13 printf("%d ",f[i][j]); 14 printf("%d\n",f[i][n]); 15 } 16 exit(0); 17 } 18 19 void dfs(int x,int y) { //x为行,y为列 20 if(x==n&&y==n+1) print(); 21 if(y==n+1) {dfs(x+1,1); return ;} 22 if(x==1||y==1) 23 for(int i=2;i<=n*n;i++) { 24 if(use[i]) continue; 25 if(x==1&&!prime[f[x][y-1]+i]) continue; 26 if(y==1&&!prime[f[x-1][y]+i]) continue; 27 f[x][y]=i; use[i]=1; 28 dfs(x,y+1); 29 f[x][y]=0; use[i]=0; 30 } 31 else for(int i=n*n;i>=2;i--) { 32 if(use[i]) continue; 33 if(!prime[f[x][y-1]+i]) continue; 34 if(!prime[f[x-1][y]+i]) continue; 35 f[x][y]=i; use[i]=1; 36 dfs(x,y+1); 37 f[x][y]=0; use[i]=0; 38 } 39 } 40 41 int main() { 42 scanf("%d",&n); 43 if(n==1) {printf("NO"); return 0;} 44 for(int i=2;i<=200;i++) //预处理200以内的素数 45 if(check(i)) prime[i]=1; 46 f[1][1]=1; use[1]=1; //左上角的格子里必须填数字1 47 dfs(1,2); 48 printf("NO"); 49 } 50 /* 51 #DFS# 52 题面要求:输出第一行、第一列之和为最小的排列方案。 53 怎样使它最小? 54 ANS:在第一行、第一列数字dfs的枚举时,i枚举顺序为1~n^2。(尽量取小) 55 而不是第一行、第一列的其他数字枚举时,i枚举顺序为n^2~1。(尽量取大) 56 PS:素数判断可以只判断左、上(已经搜索过的数)与当前和是不是素数。 57 */
如有错误请指正。