标签:国际象棋 维数 标记 out ons 回溯 time printf div
题目描述:
在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法!
这道题,很明显的回溯法
回溯法的的精髓说白了就是要有一个状态标志,然后根据这标志来决定,下一步走不走.
这里这个标志我们选用一个n*n的二维数组
#include"iostream" using namespace std; int a[100][100],ans; const int n=8; int check(int x,int y){
//检查当前皇后的位置(x,y)与其他皇后有冲突吗 // printf("正在检查%d行,%d列\n",x,y); int i,j; for(i=1;i<=n;i++) if(a[i][y]==1)//判断同行同列有没有皇后 return 0; //判断对角线 for(i=x,j=y;i>=1&&j>=1;i--,j--)//当前位置的左上, if(a[i][j]==1) return 0; for(i=x,j=y;i>=1&&j<=n;i--,j++)//右上位置 if(a[i][j]==1) return 0; return 1; } void print(){ int i,j; for(i=1;i<=n;i++) { for(j=1;j<=n;j++) cout<<a[i][j]<<" "; cout<<endl; } cout<<endl; } void dfs(int row){ // cout<<"行:"<<row<<endl; int i; if(row>n){//递归结束,进行结果的输出 ans++;//解的个数 print(); return ; } for(i=1;i<=n;i++){ //检查 if(check(row,i)){//检查当前位置可用不可用 // printf("第%d行,%d列可以用\n",row,i); a[row][i] = 1;//标记第row行第i列 dfs(row+1);//进入下一行 a[row][i] = 0; //这一步是最关键的一步,状态回溯,将之前的标志取消 } } } int main(){ cout<<"开始执行--------"<<endl; dfs(1); cout<<ans<<endl; }
标签:国际象棋 维数 标记 out ons 回溯 time printf div
原文地址:https://www.cnblogs.com/Tisou1/p/12814161.html