深入理解N皇后問題:從DFS到對角線優化

N皇后問題是一個經典的算法問題,要求在N×N的棋盤上放置N個皇后,使得它們互不攻擊。本文將全面解析該問題的解法,特別聚焦于DFS算法和對角線優化的數學原理。

問題描述

在N×N的國際象棋棋盤上放置N個皇后,要求:

  • 任意兩個皇后不在同一行

  • 任意兩個皇后不在同一列

  • 任意兩個皇后不在同一對角線

數據結構圖解

1. 棋盤表示

char g[N][N];  // 棋盤矩陣
  • '.'?表示空位

  • 'Q'?表示皇后

示例(n=4初始狀態):

. . . .
. . . .
. . . .
. . . .

2. 沖突檢測數組

bool col[N];       // 列占用標記
bool dg[N*2];      // 正對角線占用標記
bool udg[N*2];     // 反對角線占用標記
對角線索引計算:
(0,0) (0,1) (0,2) (0,3)
(1,0) (1,1) (1,2) (1,3)
(2,0) (2,1) (2,2) (2,3)
(3,0) (3,1) (3,2) (3,3)
  • 正對角線(dg)u + i(行+列)

    • 例如:(1,2)的正對角線索引=1+2=3

    • 我們發現同一個對角線的上的坐標的x,y值相加是相等的,所以我們用dg[u+i]去標記

  • 反對角線(udg)n - u + i

    • 例如:當n=4時,(1,2)的反對角線索引=4-1+2=5

    • 反對角線,我們此時不能再次使用u+i了?

    • 但為了確保索引不重疊,我們使用n - u + i

      • u增加時,n - u減小

      • i增加時,i增大

      • 這樣確保每條反對角線有唯一索引

    • 實際計算示例(n=4)

      坐標計算式索引值
      (0,3)4-0+3=77
      (1,2)4-1+2=55
      (2,1)4-2+1=33
      (3,0)4-3+0=11

算法執行流程圖解

DFS遞歸過程

dfs(0)
├─ 嘗試第0行第0列
│  ├─ 放置皇后
│  ├─ dfs(1)
│  │  ├─ 嘗試第1行第2列
│  │  │  ├─ 放置皇后
│  │  │  ├─ dfs(2)
│  │  │  │  ├─ (沖突,回溯)
│  │  │  └─ 撤銷皇后
│  │  └─ 嘗試其他列...
│  └─ 撤銷皇后
└─ 嘗試第0行第1列├─ 放置皇后├─ dfs(1)│  ├─ 嘗試第1行第3列│  │  ├─ 放置皇后│  │  ├─ dfs(2)│  │  │  ├─ 找到解│  │  │  └─ 輸出棋盤│  │  └─ 撤銷皇后│  └─ 嘗試其他列...└─ 撤銷皇后

示例解(n=4)

有效解之一:

. Q . .
. . . Q
Q . . .
. . Q .

對應的標記數組狀態:

  • col: [1, 0, 1, 0] (第0、2列被占用)

  • dg: 索引1、3、4被占用

  • udg: 索引4、5、6被占用

完整代碼

/*DFS			深度優先搜索*/
#include <stdio.h>
#include <stdbool.h>#define N 20int n;				//棋盤的大小(n*n)
char g[N][N];		//模擬棋盤,'.'表示空,'Q'表示皇后
//col表示列是否被占用,dg表示正對角線是否被占用,udg表示反對角線是否被占用
bool col[N], dg[N*2], udg[N*2];		void dfs(int u)	//u表示當前處理的行
{if (u == n)		//所有的行處理完畢,輸出解,返回遞歸{for (int i = 0;i < n;i++)	//puts函數輸出字符串,自動換行puts(g[i]);				//在二維數組g[][]中,單使用g[i]表示第i行的所有數據puts("");		//打印空格,隔開不同解return;}//嘗試在當前行的每一列放置皇后for(int i = 0;i < n;i++)//檢查列,正對角線,反對角線是否沖突if (!col[i] && !dg[u + i] && !udg[n - u + i]){g[u][i] = 'Q';		//防止皇后col[i] = dg[u + i] = udg[n - u + i] = true;		//標記占用dfs(u + 1);			//遞歸處理下一行col[i] = dg[u + i] = udg[n - u + i] = false;	//回溯,撤銷原有的標記g[u][i] = '.';		//恢復棋盤}
}int main()
{scanf("%d", &n);//初始棋盤for (int i = 0;i < n;i++)for (int j = 0;j < n;j++)g[i][j] = '.';//從第0行開始DFSdfs(0);return 0;
}

時間復雜度分析

  • 最壞情況:O(n!)(需要嘗試所有可能的排列)

  • 實際由于剪枝(沖突檢測),運行效率高于純暴力搜索

關鍵點總結

  1. 行處理順序:逐行放置皇后,避免行沖突

  2. 沖突檢測

    • 列沖突:col[i]

    • 正對角線沖突:dg[u+i]

    • 反對角線沖突:udg[n-u+i]

  3. 回溯機制:遞歸返回時撤銷所有修改

這個算法通過DFS系統地探索所有可能的解空間,同時使用剪枝技術大幅提高效率。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/80584.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/80584.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/80584.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java面試場景篇:分布式鎖的實現與組件詳解

互聯網大廠Java求職者面試&#xff1a;分布式鎖的實現與組件 在一場緊張而又充滿挑戰的面試中&#xff0c;Java架構師馬架構正面對著一位經驗豐富的面試官。以下是他們之間關于分布式鎖實現方式及相關問題的對話。 第一輪提問 面試官&#xff1a;請介紹一下分布式鎖的概念。…

關于使用 讀光-文字檢測-DBNet行檢測模型-中英-通用領域,版本問題

關于使用 讀光-文字檢測-DBNet行檢測模型-中英-通用領域&#xff0c;版本問題 pip install modelscopeSuccessfully installed certifi-2025.4.26 charset-normalizer-3.4.1 colorama-0.4.6 idna-3.10 modelscope-1.25.0 requests-2.32.3 tqdm-4.67.1 urllib3-2.4.0 pip insta…

刷刷刷刷刷RCE

云曦歷年考核 25年春開學考 RCCCE 開啟題目進行代碼審計 GET傳參傳入一個參數cmd&#xff0c;但對參數內容給了黑名單進行過濾 $blacklist /bash|nc|wget|ping|ls|cat|more|less|phpinfo|base64|echo|php|python|mv|cp|la|\-|\*|"|\>|\<|\%|\$/i; ls、cat等都…

2024江西ICPC部分題解

題目列表 A - Maliang Learning PaintingC - LiarG - Multiples of 5H - ConvolutionJ - Magic MahjongK - Magic Tree A - Maliang Learning Painting 題目來源&#xff1a;A - Maliang Learning Painting 思路分析 這是個簽到題&#xff0c;直接輸出abc即可 #include<b…

Pytorch圖像數據轉為Tensor張量

PyTorch的所有模型&#xff08;nn.Module&#xff09;都只接受Tensor格式的輸入&#xff0c;所以我們在使用圖像數據集時&#xff0c;必須將圖像轉換為Tensor格式。PyTorch提供了torchvision.transforms模塊來處理圖像數據集。torchvision.transforms模塊提供了一些常用的圖像預…

為什么vllm能夠加快大模型推理速度?

vLLM加速大模型推理的核心技術原理可分解為以下關鍵創新點&#xff1a; 一、?內存管理革命&#xff1a;PagedAttention? KV Cache分頁機制? 將傳統連續存儲的KV Cache拆分為非連續內存頁&#xff0c;類似操作系統內存分頁管理&#xff0c;消除內存碎片并實現動態分配。13B…

第十一章 多態

多態是面向對象開發過程中一個非常重要的概念。 11.1 多態概述 11.1.1 什么是多態 多態&#xff08;polymorphism&#xff09;&#xff0c;從字面理解是“多種形態&#xff0c;多種形式”&#xff0c;是一種將不同的特殊行為泛化為當個特殊記號的機制。 多態從實現的角度可劃…

RNN——循環神經網絡

一.基本結構 1.目標&#xff1a;處理序列數據&#xff08;時間序列&#xff0c;文本&#xff0c;語音等&#xff09;&#xff0c;捕捉時間維度上的依賴關系 核心機制&#xff1a;通過隱藏狀態&#xff08;hidden State&#xff09;傳遞歷史信息&#xff0c;每個時間步的輸入包…

性能提升手段--池化技術

看到hadoop代碼里有ByteBufferPool,使用池子來避免頻繁創建、銷毀ByteBuffer,減輕GC壓力,提高性能。 順便總結一下池化技術 一、什么是池化技術??? ??池化(Pooling)?? 是一種資源管理策略,通過??預先創建并復用資源??(如數據庫連接、線程、內存對象等)來提…

數據安全和合規性市場分析

一、什么是數據安全和合規性 在數據安全和合規性方面&#xff0c;存在著一系列重要的法律、法規和行業標準&#xff0c;這些規定了組織如何收集、存儲、處理和保護個人數據及其他敏感信息。企業之所以要遵守這些規定&#xff0c;是出于多方面的考量&#xff0c;既有法律責任&a…

【每日八股】復習計算機網絡 Day4:TCP 協議的其他相關問題

文章目錄 昨日內容復習已經建立了 TCP 連接&#xff0c;客戶端突然出現故障怎么辦&#xff1f;什么時候用長連接&#xff1f;短連接&#xff1f;TCP 的半連接隊列與全連接隊列&#xff1f;什么是 SYN 攻擊&#xff1f;如何避免&#xff1f;TIME_WAIT 的作用&#xff1f;過多如何…

React:<></>的存在是為了什么

1. <></> 是什么&#xff1f; <></> 是 React 的Fragment&#xff08;片段&#xff09;語法糖&#xff0c;等價于 <React.Fragment></React.Fragment>。 2. 它的作用 主要作用&#xff1a; 允許你在組件里返回多個元素&#xff0c;而不需…

cron定時任務

cron定時任務 一、Cron表達式的定義 基礎結構 Cron表達式是由空格分隔的6或7個字段組成的字符串&#xff0c;格式為&#xff1a; 秒 分 時 日 月 星期 [年]其中&#xff0c;年通常可以被省略 字段說明&#xff1a; 秒&#xff08;0-59&#xff09; 秒字段表示每分鐘的哪一…

分布式之易混淆概念

昨天寫UE寫的破防了&#xff0c;忘了寫文章&#xff0c;今天補一下分布式的一些概念。&#x1f61a; 在軟件架構領域&#xff0c;微服務、領域驅動設計&#xff08;DDD&#xff09;和分布式系統是三個高頻且容易被混淆的概念。許多開發者誤以為它們是“同一件事的不同說法”&a…

量子躍遷:Vue組件安全工程的基因重組與生態免疫(完全體終局篇)

開篇數字免疫系統的范式革命 在2025年某國際金融峰會期間&#xff0c;黑客組織利用量子計算技術對全球37個交易系統發起協同攻擊。傳統安全組件在2.7秒內集體失效&#xff0c;造成每秒超18億美元的交易漏洞。這場數字"切爾諾貝利"事件促使我們重新定義前端安全——組…

Operating System 實驗七 Linux文件系統實驗

實驗目標: 使用dd命令創建磁盤鏡像文件ext2.img并格式化為ext2文件系統,然后通過mount命令掛載到Linux主機文件系統。查看ext2文件系統的超級塊的信息,以及數據塊的數量、數據塊的大小、inode個數、空閑數據塊的數量等信息 在文件系統中創建文件xxxxx.txt(其中xxxxx為你的學…

模型識別能力錘煉及清單

大腦將注意力分配給需要消耗腦力的活動&#xff0c;通過學習技能&#xff0c;大腦也能更輕松的工作。這個時候&#xff0c;大腦負責管理注意力控制和努力控制的區域活動會大幅減少。沉浸式學習是學習一門新的語言的最佳方式&#xff0c;也是深入洞察錯綜復雜商業環境的絕佳途徑…

Android 混合開發實戰:統一 View 與 Compose 的淺色/深色主題方案

整個應用&#xff08;包括 View 和 Compose 部分&#xff09;的淺色/深色模式保持一致。以下是完整的解決方案&#xff1a; 全局配置方案 1. 基礎主題設置 在 res/values/themes.xml 和 res/values-night/themes.xml 中定義統一的主題&#xff1a; <!-- values/themes.x…

QT開發技術【QT實現桌面右下角消息】

一、效果 ![ 二、彈窗主體部分 noticewidget /* ** File name: NoticeWidget.h ** Author: ** Date: 2025-04-25 ** Brief: 通知欄控件 ** Copyright (C) 1392019713qq.com All rights reserved. */#include "../Include/NoticeWidget.h"…

在LiveGBS GB28181互聯網安防監控平臺中關于redis版本切換的方法說明

目錄 1、Redis服務2、如何切換REDIS? 2.1、停止啟動REDIS2.2、配置信令服務2.3、配置流媒體服務2.4、啟動3、搭建GB28181視頻直播平臺 1、Redis服務 在LivGBS中Redis作為數據交換、數據訂閱、數據發布的高速緩存服務。默認LiveCMS解壓目錄下會攜帶一個REDIS服務。如果已經有自…