zoukankan      html  css  js  c++  java
  • 八皇后(回溯经典)

    在8 * 8的棋盘上,摆放8个皇后,使其任意两个皇后都不能处于同一行、同一列或同一斜线上,问共有多少种摆法,并且用程序输出这些摆法。

    八皇后作为回溯法的经典例题还是值得一做的,这道题基本可以分成以下步骤:

    1.初始化棋盘,0代表没有皇后,1代表有皇后。

    2.剪枝函数(判断同一行、同一列或同一斜线上是否有皇后)

    3.回溯主程序

    4.打印棋盘

    程序如下:

     1 #include "stdafx.h"
     2 #include <stdlib.h>
     3 const int Max = 8;
     4 const int chessMen = 1;
     5 int count = 0;
     6 //初始化棋盘
     7 int chessboard[Max][Max] = {0};
     8 //打印棋盘
     9 void Print()
    10 {
    11     for(int i = 0;i< Max;i++)
    12     {
    13         for(int j = 0; j < Max;j++)
    14         {
    15             printf("%d",chessboard[i][j]);
    16             if(j == 7)
    17             {
    18                 printf("
    ");
    19             }
    20         }
    21     }
    22 }
    23 //剪枝函数
    24 int Cut(int r,int c)
    25 {
    26     //判断同列不同行的格子里有没有皇后
    27     for(int i = 0; i < Max; i++)
    28         if(chessboard[i][c] == chessMen)
    29             return 0;
    30     //判断同行不同列的格子里有没有皇后
    31     for(int j = 0; j < Max; j++)
    32         if(chessboard[r][j] == chessMen)
    33             return 0;
    34     //判断右下角斜线位置有没有皇后
    35     for(int i = r + 1,j = c + 1;i < Max&&j < Max;i++,j++)
    36         if(chessboard[i][j] == chessMen)
    37             return 0;
    38     //判断左下角斜线位置有没有皇后
    39     for(int i = r + 1,j = c - 1;i < Max&&j >= 0;i++,j--)
    40         if(chessboard[i][j] == chessMen)
    41             return 0;
    42     return 1;
    43 }
    44 //回溯主程序
    45 void BackTrack(int num,int queen)
    46 {
    47     if(num <=0 ||queen == Max)
    48     {
    49         if(queen == Max)
    50         {
    51             Print();
    52             count++;
    53             printf("
    ");
    54         }
    55     }
    56     else
    57     {
    58         int r = num / Max;
    59         int c = num % Max;
    60         //核心中的核心
    61         if(Cut(r,c))
    62         {
    63             chessboard[r][c] = chessMen;
    64             BackTrack(num - 1,queen + 1);
    65             chessboard[r][c] = 0;
    66         }
    67         BackTrack(num - 1,queen);
    68     }
    69 }
    70 int _tmain(int argc, _TCHAR* argv[])
    71 {    
    72     
    73     BackTrack(Max * Max - 1,0);
    74     printf("在%d * %d的棋盘中,%d皇后共有%d中摆法",Max,Max,Max,count);
    75     system("Pause");
    76     return 0;
    77 }

    最后回溯计算出只有88种,但是据说图论有92种。。这个我是没有找到还能优化的地方了...

  • 相关阅读:
    【每日英语】
    【百宝箱】CLion: Cound not load cache
    C# WPF:这次把文件拖出去!
    C# WPF:快把文件从桌面拖进我的窗体来!
    两个List< string>比较是否相同的N种方法,你用过哪种?
    分享套接字数据包序列化与反序列化方法
    如何从含有占位符的字符串生成一个ReactNode数组
    vscode 插件配置指北
    第十一周总结
    机场&代理商-关系图
  • 原文地址:https://www.cnblogs.com/baikequanshu/p/3406350.html
Copyright © 2011-2022 走看看