• 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 }
  • 相关阅读:
    c#遍历一个对象中所有的属性和值
    Redis和Memchaed缓存数据查询
    ASP.NET结合Redis实现分布式缓存
    C#使用Spire.Doc Word for .Net读写Word
    DataTable序列化
    ASP.NET网站不能在VS中调试
    winform窗体运行时的大小和设计时不一致
    ajax请求aspx.cs后台方法
    jQuery判断鼠标滚动方向
    使用MagickNet编辑图片
  • 原文地址:https://www.cnblogs.com/china-mjr/p/11284082.html
Copyright © 2020-2023  润新知