UVA750回溯法典例-八皇后
文章代码选自UVA750-8 Queens Chess Problem的部分代码
vj题目链接:https://vjudge.net/problem/UVA-750
由于UVA中要求按照字典序输出,下面代码进行的特殊处理
代码如下:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 int rnum[9];//rnum[x]:x列皇后的行编号 6 int solution[100]; 7 int cur=1; 8 char aim[10]; 9 10 int pout() 11 { 12 sort(solution+1,solution+93); 13 printf("{"); 14 int flag=0; 15 for(int i=1;i<93;i++) 16 { 17 if(flag)printf(","); 18 flag=1; 19 printf("%d",solution[i]); 20 } 21 printf("};"); 22 //for(int i=1;i<93;i++) 23 // printf("%d->%d\n",i,solution[i]); 24 // printf("SOLN COLUMN\n"); 25 // printf(" # 1 2 3 4 5 6 7 8\n\n"); 26 // for(int i=1;i<93;i++) 27 // { 28 // printf("%2d ",i); 29 // // 30 // sprintf(aim,"%d",solution[i]); 31 // //printf("%d->%d\n",i,solution[i]); 32 // for(int k=0;k<8;k++) 33 // printf(" %c",aim[k]); 34 // printf("\n"); 35 // } 36 return 0; 37 } 38 39 int solver(int c) 40 { 41 if(c==9) 42 {//由于该问题的结果每一组只有八个数字,为方便打表这里组合成八位的int数 43 int snum=0; 44 for(int i=1;i<9;i++) 45 snum=snum*10+(rnum[i]); 46 solution[cur++]=snum; 47 //printf("->%d\n",snum); 48 } 49 else 50 { 51 for(int r=1;r<=8;r++) 52 { 53 rnum[c]=r; 54 int ok=1; 55 for(int nc=1;nc<c;nc++) 56 { 57 //rnum[nc]行nc列 与 rnum[c]行c列 58 //检查每一个列,是否有与该皇后同行的存在 59 if(rnum[nc]==rnum[c]||rnum[nc]-nc==rnum[c]-c||rnum[nc]+nc==rnum[c]+c) 60 {ok=0;break;} 61 }//for 62 if(ok)solver(c+1); 63 }//for 64 }//else 65 return 0; 66 } 67 68 int main() 69 { 70 memset(rnum,0,sizeof(rnum)); 71 memset(solution,0,sizeof(solution)); 72 memset(aim,0,sizeof(aim)); 73 solver(1); 74 pout(); 75 return 0; 76 }
运行上述代码,得到了结果如下:
{15863724,16837425,17468253,17582463,24683175,25713864,25741863,26174835,26831475,27368514,27581463,28613574,31758246,35281746,35286471,35714286,35841726,36258174,36271485,36275184,36418572,36428571,36814752,36815724,36824175,37285146,37286415,38471625,41582736,41586372,42586137,42736815,42736851,42751863,42857136,42861357,46152837,46827135,46831752,47185263,47382516,47526138,47531682,48136275,48157263,48531726,51468273,51842736,51863724,52468317,52473861,52617483,52814736,53168247,53172864,53847162,57138642,57142863,57248136,57263148,57263184,57413862,58413627,58417263,61528374,62713584,62714853,63175824,63184275,63185247,63571428,63581427,63724815,63728514,63741825,64158273,64285713,64713528,64718253,68241753,71386425,72418536,72631485,73168524,73825164,74258136,74286135,75316824,82417536,82531746,83162574,84136275};
将其设计为数组初始化的形式,再按照UVA题目写程序:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std;//下面的初始化直接将结果输入程序,减少时间 5 int cyc[]={15863724,16837425,17468253,17582463,24683175,25713864,25741863,26174835,26831475,27368514,27581463,28613574,31758246,35281746,35286471,35714286,35841726,36258174,36271485,36275184,36418572,36428571,36814752,36815724,36824175,37285146,37286415,38471625,41582736,41586372,42586137,42736815,42736851,42751863,42857136,42861357,46152837,46827135,46831752,47185263,47382516,47526138,47531682,48136275,48157263,48531726,51468273,51842736,51863724,52468317,52473861,52617483,52814736,53168247,53172864,53847162,57138642,57142863,57248136,57263148,57263184,57413862,58413627,58417263,61528374,62713584,62714853,63175824,63184275,63185247,63571428,63581427,63724815,63728514,63741825,64158273,64285713,64713528,64718253,68241753,71386425,72418536,72631485,73168524,73825164,74258136,74286135,75316824,82417536,82531746,83162574,84136275}; 6 char aim[99][10]; 7 char psd[10]; 8 int pre() 9 { 10 memset(psd,0,sizeof(psd)); 11 for(int i=0;i<92;i++) 12 { 13 sprintf(&aim[i][1],"%d",cyc[i]); 14 aim[i][9]='\0';//重新分配成数组,方便检索 15 //printf("%s\n",&aim[i][1]); 16 } 17 return 0; 18 } 19 20 int main() 21 { 22 int n; 23 int x,y; 24 pre(); 25 scanf("%d",&n); 26 while(n--) 27 { 28 scanf("%d%d",&x,&y); 29 printf("SOLN COLUMN\n"); 30 printf(" # 1 2 3 4 5 6 7 8\n\n"); 31 int kase=0; 32 char m=x+'0'; 33 for(int i=0;i<92;i++) 34 { 35 if(aim[i][y]==m) 36 { 37 printf("%2d ",++kase); 38 for(int k=1;k<9;k++) 39 printf(" %c",aim[i][k]); 40 printf("\n"); 41 } 42 } 43 if(n!=0)printf("\n");//注意空行问题,最后一组的最后没有空行 44 } 45 return 0; 46 }