图论-回溯-八皇后
八皇后问题
题解:
1 /*不列出情况*/ 2 3 #include<stdio.h> 4 #define N 8 5 int tot=0; 6 int vis[3][15]= {0}; 7 void search(int cur) 8 { 9 int i,j; 10 if(cur==N) 11 tot++; 12 else 13 for(i=0; i<N; i++) //cur代表行,i代表列 14 { 15 if(!vis[0][i]&&!vis[1][cur+i]&&!vis[2][cur-i+N])//在同一主对角线上的元素的特点是行减列的值相同,在同一副对角线上的元素的特点是行加列的值相同 16 { 17 vis[0][i]=vis[1][cur+i]=vis[2][N+cur-i]=1; 18 search(cur+1); 19 vis[0][i]=vis[1][cur+i]=vis[2][N+cur-i]=0 ; 20 } 21 } 22 } 23 int main() 24 { 25 26 search(0); 27 printf("八皇后摆法总数: %d\n",tot); 28 return 0; 29 }
或:
1 /*列出各种情况:*/ 2 3 #include<stdio.h> 4 int chess[8][8]= {0}; 5 int a[8],b[15],c[15];//分别代表列,富对角线,主对角线 6 int sum=0; //统计所有摆法 7 void PutQueen(int n) 8 { 9 int col,i,j; 10 for(col=0; col<8; col++) //从第零列到第8列枚举 11 { 12 if(a[col]&& b[n+col] && c[n-col+7]) //判断安全位置 13 { 14 chess[n][col]=1; //放置皇后 15 a[col]=0; 16 b[n+col]=0; 17 c[n-col+7]=0;//和算法书上的区别:这里是先进行判断,整个程序都是在安全位置的前提下进行的,而算法书上是后进行判断所以这里到7就可以确定 18 if(n==7) 19 { 20 sum++; 21 printf("第%d种可能的摆法:\n",sum); //输出皇后摆法 22 for(i=0; i<8; i++) 23 { 24 printf("\t\t"); 25 for(j=0; j<8; j++) 26 printf("%d ",chess[i][j]); 27 printf("\n"); 28 } 29 printf("\n"); 30 if(sum%10==0) //每输出十种暂停因为太多,一次性输出的话看不全 31 { 32 printf("按回车键继续……"); 33 getchar(); 34 } 35 } 36 else 37 PutQueen(n+1); //递归 38 chess[n][col]=0; //取消皇后 39 b[n+col]=1; 40 c[n-col+7]=1; 41 a[col]=1; 42 } 43 } 44 } 45 int main() 46 { 47 int i; 48 for(i=0; i<8; ++i) 49 a[i]=1; 50 for(i=0; i<15; ++i) 51 { 52 b[i]=1; 53 c[i]=1; 54 } 55 PutQueen(0); 56 printf("八皇后摆法总数: %d\n",sum); 57 return 0; 58 }