1 条题解

  • 0
    @ 2026-4-7 11:03:23
    很经典的dfs入门 写法很多各有千秋这里用y总的写法
    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    /* 
      本题是n皇后问题 是一个很好的dfs问题
      这里我们简单介绍:是否主动dfs(不选):选数:  for 循环枚举 → 不选 = 自动跳过 → 不用写
                                             N 皇后:一格一格走 → 不选 = 必须手动往下走 → 必须写  
      如何剪枝:利用游戏规则不能重复进行:第一思维:转化二维进行标记数组:但是回溯消去标记会影响之前标记
                 优化思路:标记某一行/列/对角即可:h[i]即这行不可以 l[j]表示这列再不可以
    			                                   zd[i+j]表示这个对角不可以 /(主对角)
    											   df[i-j+n]表示这个负对角不可以 \
      okdfs思考:1含义:dfs(x,y,cnt)当前遍历棋局与释放皇后数
                 2起点 dfs(0,0,0) 终点dfs(n了)看cnt是不是==n
    			 3转移:因为没有for我们要手动转移与放于不放
    			    1 dfs(x,y+1) if(y==m)x++ y=0即可
    				2不放:dfs(x,y+1,cnt)直接 放:dfs(x,y+1,cnt+1)--小判定+标记											                                          
    */ 
    const int N=15;
    int h[N],l[N],zd[2*N],fd[2*N];//这个注意*2 
    int ans;
    int n;   
    void dfs(int x,int y,int cnt)//0---n-1
    {
      //转移方程
      if(y==n) x++,y=0;
      //终点
      if(x==n)
      {
      	if(cnt==n) ans++;
    	return;   
      } 
      //1不选 
      dfs(x,y+1,cnt);
      //2选
      if(!h[x]&&!l[y]&&!zd[x+y]&&!fd[x-y+n])
      {
      	h[x]=l[y]=zd[x+y]=fd[x-y+n]=1;
      	dfs(x,y+1,cnt+1);
      	h[x]=l[y]=zd[x+y]=fd[x-y+n]=0;
      }	
    }        
    signed main()
    { std::ios::sync_with_stdio(0);
      cin.tie(0),cout.tie(0);
      cin>>n;
      dfs(0,0,0);
      cout<<ans<<"\n";	
    	return 0;
    }

    信息

    ID
    451
    时间
    1000ms
    内存
    256MiB
    难度
    3
    标签
    递交数
    85
    已通过
    48
    上传者