EOJ-1148 质数阵
http://acm.cs.ecnu.edu.cn/problem.php?problemid=1148
题意:在n*n的矩阵中填入1-n^2,使得任意两个相邻的数字之和为质数,并且输出符合条件的最小序列(就是指小数尽量在前)。
dfs,从小数开始填,从左到右,从上到下的方法进行搜索,可以使得判断条件仅考虑与上面数字的和以及左面数字的和为质数,并且以此方法第一个填完的表即是最小序列。
但方法依然比较朴素,故tle,无奈打表。
由于tle,仅提供思路
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<cstdlib> 6 #include<cmath> 7 #include<string> 8 #include<cctype> 9 #include<map> 10 using namespace std; 11 int n; 12 int mat[15][15]; 13 bool p[205],v[105]; 14 bool finish; 15 void PrimeList(){ //打出质数表 16 p[1]=0; 17 for(int i=2;i<=205;i++) 18 p[i]=1; 19 for(int i=2;i<=sqrt(205.0);i++) 20 for(int j=2;j<=205/i;j++) 21 p[i*j]=0; 22 /*for(int i=2;i<=205;i++) 23 if(p[i])cout<<i<<" ";*/ 24 } 25 void dfs(int depth){ 26 if(finish)return; 27 if(depth-1==n*n){ 28 finish=1; //完成 29 //printf("end\n"); 30 } 31 for(int i=1;i<=n*n && finish==0;i++){ 32 if(v[i]==0){ 33 v[i]=1; 34 int x=(depth-1)/n,y=(depth-1)%n; //depth表示即将填入第depth个数,i是将要填的数,x与y表示坐标 35 int f=1; 36 if(x) 37 if(p[mat[x-1][y]+i]==0) f=0; //不是最靠上或最靠左就进行判断 38 if(y) 39 if(p[mat[x][y-1]+i]==0) f=0; 40 if(f){ 41 mat[x][y]=i; 42 //printf("i=%d,depth=%d \n",i,depth); 43 dfs(depth+1); 44 } 45 v[i]=0; 46 } 47 } 48 return ; 49 } 50 int main(){ 51 PrimeList(); 52 while(cin>>n){ 53 memset(v,0,sizeof(v)); 54 finish=0; 55 dfs(1); 56 if(finish){ 57 for(int i=0;i<n;i++) 58 for(int j=0;j<n;j++){ 59 printf("%d",mat[i][j]); 60 if(j==n-1)printf("\n"); 61 else printf(" "); 62 } 63 } 64 else printf("no answer\n"); 65 } 66 return 0; 67 }
打表AC:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<cstdlib> 6 #include<cmath> 7 #include<string> 8 using namespace std; 9 int main(){ 10 int n; 11 while(cin>>n){ 12 if(n==1) 13 printf("1\n"); 14 else if (n==2) 15 printf("1 2\n4 3\n"); 16 else if (n==3) 17 printf("no answer\n"); 18 else if (n==4) 19 printf("1 2 11 12\n4 9 8 5\n7 10 3 14\n6 13 16 15\n"); 20 else if (n==5) 21 printf("1 2 3 4 7\n6 5 8 15 22\n25 18 23 14 9\n16 13 24 17 20\n21 10 19 12 11\n"); 22 else if (n==6) 23 printf("1 2 3 4 7 6\n10 21 16 13 24 5\n19 22 25 18 23 14\n12 31 36 35 8 15\n29 30 17 26 33 28\n32 11 20 27 34 9\n"); 24 else if (n==7) 25 printf("1 2 3 4 7 6 5\n10 9 8 15 16 13 18\n19 22 21 46 37 24 23\n12 49 40 43 30 29 14\n35 48 31 36 17 44 39\n38 41 42 11 26 45 28\n33 20 47 32 27 34 25\n"); 26 else if (n==8) 27 printf("1 2 3 4 7 6 5 8\n10 9 14 15 16 13 18 11\n19 22 39 28 25 34 49 12\n24 37 64 33 46 55 54 17\n23 60 43 40 61 42 29 44\n56 41 30 31 36 47 32 27\n57 26 53 48 35 62 21 52\n50 63 20 59 38 45 58 51\n"); 28 else if (n==9) 29 printf("1 2 3 4 7 6 5 8 9\n10 21 16 13 24 17 12 11 20\n19 22 15 28 43 30 29 18 23\n34 25 46 33 40 31 42 41 38\n27 76 37 64 49 48 59 68 69\n52 61 36 67 60 53 44 39 70\n79 78 35 72 77 74 63 50 81\n58 73 66 65 62 75 26 57 32\n55 54 47 14 45 56 71 80 51\n"); 30 else if (n==10) 31 printf("1 2 3 4 7 6 5 8 9 10\n12 11 20 27 16 13 18 23 14 33\n17 26 21 32 15 28 19 24 29 38\n30 41 62 35 44 39 22 37 42 59\n31 48 65 36 53 50 51 46 25 54\n40 61 66 43 60 47 56 57 82 49\n63 76 73 58 91 90 83 74 75 88\n86 81 100 79 72 77 80 99 52 85\n93 70 97 34 67 96 71 68 45 64\n98 69 94 55 84 95 78 89 92 87\n"); 32 } 33 return 0; 34 }