zoukankan      html  css  js  c++  java
  • 八皇后问题

    八皇后问题,是一个古老而著名的问题,是回溯算法的典型案例。该问题是国际西洋棋棋手马克斯·贝瑟尔于1848年提出:在8×8格的国际象棋上摆放八个皇后,使其不能互相攻击,即任意两个皇后都不能处于同一行、同一列或同一斜线上,问有多少种摆法。

    八皇后问题可以用 dfs 来解决

    第一种: 根据行 (row) 来dfs

     1 #include <cstdio>
     2 #include <string>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <string.h>
     6 #include <math.h>
     7 
     8 using namespace std;
     9 
    10 const int maxn = 100;
    11 
    12 int vis[maxn];
    13 int cnt = 0;
    14 
    15 bool check(int row,int col)
    16 {
    17     for (int i=0;i<row;i++)
    18     {
    19         if (vis[i] == col || abs(vis[i] - col) == abs(i-row))
    20             return false;
    21     }
    22     return true;
    23 }
    24 
    25 void dfs(int row) // row代表搜索到第几行
    26 {
    27     if (row == 8)
    28     {
    29         cnt++;
    30         return ;
    31     }
    32     else
    33     {
    34         for (int col = 0;col<8;col++)
    35         {
    36             if (check(row,col))
    37             {
    38                 vis[row] = col;
    39                 dfs(row+1);
    40             }
    41         }
    42     }
    43 }
    44 
    45 int main()
    46 {
    47     dfs(0);
    48     printf("%d
    ",cnt);
    49     return 0;
    50 }

    方法二:

    根据列 (col) 来dfs

     1 #include <cstdio>
     2 #include <string>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <string.h>
     6 #include <math.h>
     7 
     8 using namespace std;
     9 
    10 const int maxn = 100;
    11 
    12 int vis[maxn],a[maxn][maxn];
    13 int cnt = 0;
    14 
    15 
    16 bool check(int row,int col)
    17 {
    18     for (int i=0;i<col;i++)
    19     {
    20         if (vis[i] == row || abs(vis[i] - row) == abs(i-col))
    21             return false;
    22     }
    23     return true;
    24 }
    25 
    26 void dfs(int col) //col代表搜索到第几列
    27 {
    28     if (col == 8)
    29     {
    30         cnt++;
    31         return ;
    32     }
    33     else
    34     {
    35         for (int row = 0;row<8;row++)
    36         {
    37             if (check(row,col))
    38             {
    39                 vis[col] = row;
    40                 dfs(col+1);
    41             }
    42         }
    43     }
    44 }
    45 
    46 int main()
    47 {
    48     dfs(0);
    49     printf("%d
    ",cnt);
    50     return 0;
    51 }

    VJudge上的一道八皇后的问题:

    在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方。Input无输入。Output按给定顺序和格式输出所有八皇后问题的解(见Sample Output)。

    无输入。

    
    

    Sample Output

    No. 1
    1 0 0 0 0 0 0 0 
    0 0 0 0 0 0 1 0 
    0 0 0 0 1 0 0 0 
    0 0 0 0 0 0 0 1 
    0 1 0 0 0 0 0 0 
    0 0 0 1 0 0 0 0 
    0 0 0 0 0 1 0 0 
    0 0 1 0 0 0 0 0 
    No. 2
    1 0 0 0 0 0 0 0 
    0 0 0 0 0 0 1 0 
    0 0 0 1 0 0 0 0 
    0 0 0 0 0 1 0 0 
    0 0 0 0 0 0 0 1 
    0 1 0 0 0 0 0 0 
    0 0 0 0 1 0 0 0 
    0 0 1 0 0 0 0 0 
    No. 3
    1 0 0 0 0 0 0 0 
    0 0 0 0 0 1 0 0 
    0 0 0 0 0 0 0 1 
    0 0 1 0 0 0 0 0 
    0 0 0 0 0 0 1 0 
    0 0 0 1 0 0 0 0 
    0 1 0 0 0 0 0 0 
    0 0 0 0 1 0 0 0 
    No. 4
    1 0 0 0 0 0 0 0 
    0 0 0 0 1 0 0 0 
    0 0 0 0 0 0 0 1 
    0 0 0 0 0 1 0 0 
    0 0 1 0 0 0 0 0 
    0 0 0 0 0 0 1 0 
    0 1 0 0 0 0 0 0 
    0 0 0 1 0 0 0 0 
    No. 5
    0 0 0 0 0 1 0 0 
    1 0 0 0 0 0 0 0 
    0 0 0 0 1 0 0 0 
    0 1 0 0 0 0 0 0 
    0 0 0 0 0 0 0 1 
    0 0 1 0 0 0 0 0 
    0 0 0 0 0 0 1 0 
    0 0 0 1 0 0 0 0 
    No. 6
    0 0 0 1 0 0 0 0 
    1 0 0 0 0 0 0 0 
    0 0 0 0 1 0 0 0 
    0 0 0 0 0 0 0 1 
    0 1 0 0 0 0 0 0 
    0 0 0 0 0 0 1 0 
    0 0 1 0 0 0 0 0 
    0 0 0 0 0 1 0 0 
    No. 7
    0 0 0 0 1 0 0 0 
    1 0 0 0 0 0 0 0 
    0 0 0 0 0 0 0 1 
    0 0 0 1 0 0 0 0 
    0 1 0 0 0 0 0 0 
    0 0 0 0 0 0 1 0 
    0 0 1 0 0 0 0 0 
    0 0 0 0 0 1 0 0 
    No. 8
    0 0 1 0 0 0 0 0 
    1 0 0 0 0 0 0 0 
    0 0 0 0 0 0 1 0 
    0 0 0 0 1 0 0 0 
    0 0 0 0 0 0 0 1 
    0 1 0 0 0 0 0 0 
    0 0 0 1 0 0 0 0 
    0 0 0 0 0 1 0 0 
    No. 9
    0 0 0 0 1 0 0 0 
    1 0 0 0 0 0 0 0 
    0 0 0 1 0 0 0 0 
    0 0 0 0 0 1 0 0 
    0 0 0 0 0 0 0 1 
    0 1 0 0 0 0 0 0 
    0 0 0 0 0 0 1 0 
    0 0 1 0 0 0 0 0 
    ...以下省略


    思路:其实就是多了一个标记数组和一个 print 函数

    AC代码:
     1 #include <cstdio>
     2 #include <string>
     3 #include <iostream>
     4 #include <algorithm>
     5 #include <string.h>
     6 #include <math.h>
     7 
     8 using namespace std;
     9 
    10 const int maxn = 100;
    11 
    12 int vis[maxn],a[maxn][maxn];
    13 int cnt = 0;
    14 int t = 1;
    15 
    16 
    17 void print()
    18 {
    19     cout << "No. " << t++ << endl;
    20     for (int i=0;i<8;i++)
    21     {
    22         for (int j=0;j<8;j++)
    23         {
    24             cout << a[i][j] << ' ';
    25         }
    26         printf("
    ");
    27     }
    28 }
    29 
    30 
    31 bool check(int row,int col)
    32 {
    33     for (int i=0;i<col;i++)
    34     {
    35         if (vis[i] == row || abs(vis[i] - row) == abs(i-col))
    36             return false;
    37     }
    38     return true;
    39 }
    40 
    41 void dfs(int col)
    42 {
    43     if (col == 8)
    44     {
    45         print();
    46         return ;
    47     }
    48     else
    49     {
    50         for (int row = 0;row<8;row++)
    51         {
    52             if (check(row,col))
    53             {
    54                 vis[col] = row;
    55                 a[row][col] = 1;
    56                 dfs(col+1);
    57                 a[row][col] = 0;
    58             }
    59         }
    60     }
    61 }
    62 
    63 int main()
    64 {
    65     dfs(0);
    66     return 0;
    67 }
  • 相关阅读:
    线程安全(上)--彻底搞懂volatile关键字
    数据库设计三大范式
    1、框架及环境搭建
    约瑟夫问题
    链表(上):如何实现LRU缓存淘汰算法?
    为什么很多编程语言中数组都是从 0 开始编号?
    mac 终端命令小结
    复杂度分析(下):浅析最好、最坏、平均、均摊时间复杂度
    复杂度分析(上):如何分析、统计算法的执行效率和资源消耗?
    程序员少走弯路的10条忠告和成就一生的10个经典故事
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/11171853.html
Copyright © 2011-2022 走看看