zoukankan      html  css  js  c++  java
  • Eight Queens UVa 750

    当时就觉得回溯法学的不是很好,在处理dp多状态问题前,温习一遍回溯法:把待求解的问题分成不太多的步骤,每个步骤只有不太多的选择,就可以考虑回溯法。

    普通八皇后思路:从64格子中选8个格子,枚举的话一共有$C^{8}_{64}=4.426X10^{9}$解法,不爆才怪。
    观察基本性质,每一行只能有一个皇后,所以最多只有$8!$种枚举可能。在实际操作的时候,状态树伸展肯定比这个值还要小,因为和之前的状态已经发生冲突,递归函数就不会再调用自身,而是返回上一层调用,这种现象被称为回溯(backtracking)。 回溯的关键在于回到上层调用时,要把改过去的状态改回来!否则原来状态被改变就不是原状态了。


    代码:

     1 int tot;
     2 bool attacked[3][16];// 0 1 2分别表示是否被前面的皇后占据了列,左斜线,右斜线, 后面表示棋盘长度(8皇后有15斜)
     3 
     4 void search(int a){ //逐行搜索
     5     if(a==n){
     6         tot++; //递归边界,到了这里表示已经圆满完成
     7     }
     8     else{
     9         for(int i=0;i<n;i++){ //对于这一行,判断这一列能不能放
    10             if(!attacked[0][i]&&!attacked[1][a+i]&&!attacked[2][n-a+i]){
    11                 //尝试放置
    12                 // cell[a] = i; //记录这行放置的列,用于打印
    13                 attacked[0][i] = true;
    14                 attacked[1][a+i] = true;
    15                 attacked[2][n-a+i] = true;
    16                 search(a+1);
    17                 //调用完毕后一定要把状态改回来!
    18                 //也就是说改变的状态是给之后的子状态用的,而不能影响同层其他结构
    19                 attacked[0][i] = false;
    20                 attacked[1][a+i] = false;
    21                 attacked[2][n-a+i] = false;
    22             }
    23         }
    24     }
    25 }
    26 
    27 int main(){
    28     cin>>n; //棋盘大小
    29     tot = 0;
    30     memset(attacked,0,sizeof(attacked));
    31     
    32     search(0);//从第0行开始
    33     cout<<tot;
    34 }
    View Code

    解题代码:

     1 //
     2 //  main.cpp
     3 //  8 QUEENS
     4 //
     5 //  Created by Yanbin GONG on 12/3/2018.
     6 //  Copyright © 2018 Yanbin GONG. All rights reserved.
     7 //
     8 
     9 #include <iostream>
    10 #include <stdio.h>
    11 #include <string>
    12 #include <string.h>
    13 #define N 8
    14 
    15 int n;
    16 bool vis[3][2*N];
    17 int r, c, kase;
    18 int ans[N];
    19 
    20 void search(int cur)
    21 {
    22     if (cur == N)
    23     {
    24         printf("%2d      ", ++kase);
    25         for (int i = 0; i < N; i++)
    26             printf("%d%s", ans[i]+1, (i==N-1) ? "
    " : " ");
    27         return;
    28     }
    29     if (cur == c)  search(cur+1);
    30     else
    31     {
    32         for (int i = 0; i < N; i++)
    33             if (!vis[0][i] && !vis[1][cur-i+N] && !vis[2][cur+i])
    34             {
    35                 ans[cur] = i;
    36                 vis[0][i] = vis[1][cur-i+N] = vis[2][cur+i] = 1;
    37                 search(cur+1);
    38                 vis[0][i] = vis[1][cur-i+N] = vis[2][cur+i] = 0;
    39             }
    40     }
    41 }
    42 
    43 int main()
    44 {
    45     scanf("%d", &n);
    46     while (n--)
    47     {
    48         scanf("%d%d", &r, &c);
    49         r--;
    50         c--;
    51         memset(vis, 0, sizeof(vis));
    52         vis[0][r] = 1;
    53         vis[1][c-r+N] = 1;
    54         vis[2][c+r] = 1;
    55         ans[c] = r;
    56         kase = 0;
    57         printf("SOLN       COLUMN
    ");
    58         printf(" #      1 2 3 4 5 6 7 8
    
    ");
    59         search(0);
    60         if (n)  printf("
    ");
    61     }
    62     return 0;
    63 }
    View Code
  • 相关阅读:
    深入理解 IE haslayout
    electron的应用
    自动化批量录入Web系统
    Flask + Vue的一个示例
    如何从git仓库里下载单个文件夹
    Django项目设置首页
    简单更改Django Admin登录页面
    Flask web项目使用.flaskenv文件
    Flask 里url_for的使用
    使用Flask-migrate迁移数据库
  • 原文地址:https://www.cnblogs.com/cmbyn/p/8548865.html
Copyright © 2011-2022 走看看