• P1219八皇后


    这个题是一道USACO的经典dfs,与我见面的时间起码七个月了。

     放置n个皇后于n*n棋盘,他们不能互相吃(行,列,对角线),问有几种摆法?于是想到了dfs(自我认为有图的就不用DP)。首先确定好了要枚举的是第i行,边界则是搜索到了n+1行,其次循环判断第j列可不可以放,如果可以放就把这个点同一行以及同一列打上标记,然后继续搜索,回溯,将标记抹去。在这里我们要设一个二维flag来打标记,flag[1][j]=1,flag[2][i+j]=1,flag[3][i-j+n]=1

    1.dfs枚举什么要想清楚,这种情况下只需要求解行和列即可,所以只枚举行或列就行

    2.对角线的表示方法:x+y相同时为左下到右上,x-y相同时为坐上到右下

    3.考虑时间复杂度的话直接给点打标记,别用bool flag看能不能继续,这样慢

    代码

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<string>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cmath>
     7 using namespace std;
     8 int a[50];
     9 int flag[50][50];
    10 int n;
    11 int cnt=0;
    12 void dfs(int i){//枚举到了第i行
    13     if(i>n){//结束了 
    14         cnt++;
    15         if(cnt<=3){
    16             for(int i=1;i<=n;i++){//每次会自动更新 
    17                 cout<<a[i]<<" ";
    18             }
    19             cout<<endl; 
    20         }    
    21     return;
    22     }
    23     for(int j=1;j<=n;j++){
    24         if(flag[1][j]==0&&flag[2][i+j]==0&&flag[3][i-j+n]==0){
    25             a[i]=j;
    26             flag[1][j]=1;
    27             flag[2][i+j]=1;//对角线 
    28             flag[3][i-j+n]=1;
    29             dfs(i+1);
    30             flag[1][j]=0;
    31             flag[2][i+j]=0;
    32             flag[3][i-j+n]=0;
    33         }
    34     }
    35 }
    36 int main(){
    37     cin>>n;
    38     dfs(1);
    39     cout<<cnt;
    40 }
  • 相关阅读:
    解决ftp的pasv模式下iptables设置问题
    linux修改运行中的脚本
    shell脚本——列出质数
    转载:tomcat设置https的两种方式
    Centos缺少ifconfig命令
    转载:MySQL 数据库设计总结
    转载:HTML5视频推流方案
    转载:Linux五种方案快速恢复你的系统
    转载:HT可视化案例
    转载:21种JavaScript设计模式最新记录(含图和示例)
  • 原文地址:https://www.cnblogs.com/china-mjr/p/11284082.html
Copyright © 2020-2023  润新知