回溯算法+對稱剪枝——從八皇后問題到數獨問題(二)

引入:

本節我們進一步完善八皇后問題,學習剪枝、八皇后殘局問題 進一步領會邏輯編程的概念,深入體會回溯算法,回顧上一節提到的啟發搜索策略。

回顧:

八皇后問題:我們需要在一個空棋盤上放置 n 個皇后,使得任意兩個皇后不能在同一行、同一列或同一對角線上。

我們使用回溯算法逐行嘗試放置皇后,并通過沖突檢測剪枝無效的分支實現。

def spin(row):  # 回溯算法def is_valid(row, col):  def prt():# 主程序入口
spin(0)  # 從第 0 行開始求解
print(f"總共有 {sol_num} 種解法。")

現在問題在于,當我們輸入n=10時,解已經輸出2680個了,?跑了大概十幾秒鐘才出來。這時我們發現,這其中很大一部分解之間是可以通過旋轉對稱得到的,如果能消除這些由旋轉對稱得到的解,是否能提高速度呢?

顯然是可以的,在應用“對稱剪枝”后,n=10的輸出幾乎是一瞬間的事。

那么,剪枝是什么呢?

剪枝

剪枝就是在搜索或計算過程中提前終止無效路徑,從而減少不必要的計算。?

我們在上一節似乎做過這件事!

# 嘗試在當前行的每一列放置皇后
for col in range(n):if is_valid(row, col):  # 如果當前位置有效board[row] = col  # 放置皇后spin(row + 1)  # 遞歸處理下一行board[row] = -1  # 回溯,撤銷放置

沒錯,上一節設定is_valid()函數的手段就是剪枝!

通過is_valid()函數判斷該節點是否有解,若無解返回 False,則直接跳過后續遞歸,因為從這個樹杈長出去的其他枝干都無解,就剪枝了。

剪枝的類型

可行性剪枝:

當前節點不滿足約束條件,則剪枝。

最優性剪枝:

求最優解時,若當前局部解已劣于已知最優解,則剪枝。

啟發式剪枝:

利用經驗規則(啟發式函數)優先剪掉低概率分支。

還有接下來的

對稱剪枝:

若兩個解(或部分解)可以通過旋轉、鏡像、置換等對稱操作相互轉換,則它們是對稱等價的。

對稱剪枝的實現

顯然,將棋盤沿對稱軸分兩半,從第一行看兩側的遍歷路徑總是一樣的,因此我們考慮只計算一半情況的解。

但棋盤并不總是偶數X偶數的,遇到奇數怎么辦?

很簡單,單獨計算中間這一行即可!

因此,當棋盤為偶數時,我們只計算第一行一半的解,如果是奇數,則加上中間一列產生的解:

 # 對稱性剪枝:限制第一行的皇后位置if n > 0:for col in range(n // 2):  # 只考慮第一行的一半列board[0] = colspin(1)  # 從第二行開始遞歸# 如果 n 是奇數,單獨處理中間列if n % 2 == 1:board[0] = n // 2spin(1)

靜態剪枝 VS 動態剪枝

你可能想問:為什么只對第一行剪枝,第二行第三行呢?是不是剪得越多算得越快呢?

實則不然,這就是對稱剪枝策略的核心——通常我們只對搜索樹的淺層(如第一行)進行靜態剪枝。

我們之所以能對第一行對稱剪枝是因為其對稱性未被破壞

而一旦放置皇后后,后續的對稱性就會被破壞:例如第一行皇后放在列0,棋盤就會失去90°旋轉對稱性。

因此進行深層剪枝時,往往需要動態判斷是否有某種對稱性,其計算成本(包括分解和遞歸)和動態存儲空間都是階乘級的上漲。

結論:雖然動態剪枝減少了節點數,但增加的判斷時間反而導致總耗時上升。

因此我們只對已知初始狀態的第一行進行對稱剪枝!

完整代碼僅僅是在之前代碼上添加了對稱性剪枝這一部分:

def solve_n_queens(n):def is_valid(board, row, col):"""檢查當前位置 (row, col) 是否有效"""for i in range(row):  if board[i] == col or abs(i - row) == abs(board[i] - col):return Falsereturn Truedef spin(row):"""回溯函數"""nonlocal sol_numif row == n:  # 如果所有行都放置了皇后sol_num += 1returnfor col in range(n):if is_valid(board, row, col):  # 剪枝:只有有效位置才繼續board[row] = col  # 放置皇后spin(row + 1)  # 遞歸處理下一行board[row] = -1  # 回溯,撤銷放置# 初始化board = [-1] * n  # board[i] 表示第 i 行中皇后所在的列號sol_num = 0# 對稱性剪枝:限制第一行的皇后位置if n > 0:for col in range(n // 2):  # 只考慮第一行的一半列board[0] = colspin(1)  # 從第二行開始遞歸# 如果 n 是奇數,單獨處理中間列if n % 2 == 1:board[0] = n // 2spin(1)return sol_numn = int(input("請輸入棋盤大小 n:"))
sol_num = solve_n_queens(n)
print(f"總共有 {sol_num} 種解法。")

皇后殘局問題

在一個 n x n 的國際象棋棋盤上,已放置若干皇后且互不攻擊,需繼續放置剩余皇后至 n 個,滿足任意兩皇后不在同一行、列或對角線上。

輸入:

  • 輸入一個n,代表棋盤的大小。
  • 輸入一個二維 n x n 的棋盤狀態,其中部分格子已經有皇后(用‘Q’表示),其余格子為空(用?'.'?表示)。
4
.Q..
...Q
....
....

輸出:

  • 如果存在解,則輸出所有可能的完整解(即棋盤上放置了?n?個互不攻擊的皇后)。
  • 如果無解,則輸出“無解”。
解法 1:
.Q..
...Q
Q...
..Q.共找到 1 種解法。

實現思路

我們考慮相較于一般皇后問題,殘局問題做了哪些改變?我們應該如何應對?

(1)?初始棋盤狀態

棋盤已經部分皇后——遍歷棋盤,保留在board中。

(2)?約束條件

固定的皇后增加了約束條件:新皇后不僅要滿足自身約束規則,還須與已固定的皇后兼容——輸入時先對殘局檢查沖突,放入新皇后時直接跳過這些行。

(3)?解空間

固定的皇后減少了搜索空間——直接跳過。

若固定皇后間存在沖突,則直接無解。

因此,修改原思路:

① 初始化與解析:首先初始化容器并解析棋盤。

② 初始檢查:檢查初始棋盤自身是否沖突

③ 調用回溯函數:不沖突則調用回溯函數

④ 結束判斷:回溯函數先檢查當前是否滿足結束條件(所有行都有皇后)

⑤?遍歷每一列:若這一列有固定皇后則跳過

⑥ 約束條件:否則判斷是否滿足約束條件。若滿足,則保存當前狀態,同時為了下一次遍歷到這里時這一層是空的(有皇后就會被略過)要將這一層還原為空,接著處理下一行。

⑦ 如果不滿足約束條件則自動判斷當前是否是這一行的最后一個元素,如果是,證明這一行無論皇后放在哪都無解,因此自動返回上一行重新找解

⑧ 如果不是,就繼續遍歷下一列直到找到可以放皇后的位置。


代碼實現:

一、初始化與解析:

初始化列表參考上一節:

# 初始化
board = [-1] * n  # 當前棋盤狀態(-1 表示未放置皇后)
solutions = []  # 存儲所有解
sol_num = 0

首先考慮如何接收這個殘局,

在上一節中,我們用列表board[]保存每一行皇后的位置,
因此我們的任務是如何從nxn的輸入中讀取Q的位置存進board[]列表中。

由于輸入是 n x n 的,我們使用for_in_range(n)循環n次接收n行的輸入,并將其存入初始表格initial_board[]中。

initial_board = [input().strip() for _ in range(n)]  # 接收一維數組

其中 for _ in 僅表示循環 n 次,不關心當前迭代的索引,strip()去掉每一行輸入的換行符。

輸入后initial_board的內容是:

initial_board = ['.Q..', '...Q', '....', '....']

接著直接調用問題解決函數:

if __name__ == "__main__":n = int(input("請輸入棋盤大小 n:"))print("請輸入初始棋盤狀態('Q' 表示皇后,'.' 表示空位):")initial_board = [input().strip() for _ in range(n)]  # 接收一維數組solve_n_queens_with_given_board(n, initial_board)

接著是如何解析initial_board[]中皇后的位置,我們考慮遍歷每一個元素“字符串”,在這個字符串中尋找是否有'Q'字符,如果有就在board對應位置保存,沒有就跳過。

 # 解析初始棋盤
for r in range(n):if initial_board第r元素有'Q':c = 'Q'的位置board[第r元素] = 'Q'的位置else:pass

那么如何從字符串中找指定字符呢?

我們想到index()函數,他會返回對象中與要找字符匹配的第一個元素的下標。

X = '1919810'
print(X.index('9'))
#輸出1

代碼也就很容易想到了:

 # 解析初始棋盤for r in range(n):try:c = initial_board[r].index('Q')  # 找到 'Q' 的列索引board[r] = c  # 固定該位置except ValueError:pass  # 如果該行沒有 'Q',跳過

二、初始檢查:檢查初始棋盤自身是否沖突

由于上一節的約束條件在這里不變,因此保留is_valid()判斷函數。

那么接下來的任務就是檢查初始棋盤是否沖突了

剛剛我們將initial_board的內容放到了board中,因此我們對board每一元素遍歷,如果其值不為-1證明這一行有固定皇后,觸發沖突判斷

is_valid()的參數列表是

def is_valid(board, row, col):

因此我們還要把當前位置傳給他,假設遍歷到第r行,且有'Q'元素,則其位置為board[r],即縱坐標為board[r]:

def is_valid(board, r, board[r]):

完整代碼:?

    # 檢查初始棋盤是否有沖突for r in range(n):if board[r] != -1:  # 如果當前行有固定皇后if not is_valid(board, r, board[r]):print("無解")return

三、回溯算法:?

由于固定皇后的存在,解空間減小了,因此遍歷行時,會有兩種情況:

①該行已有固定皇后,則檢測是否沖突。

②該行為空,則和普通皇后問題一樣進行列遍歷找地方放皇后。

當然,在執行遍歷行前,還要優先進行終點判定:

如果當前行是最后一行則將棋盤狀態保存在result中,[:]代表選擇全部。同時解數量加一。

if row == n:  # 如果所有行都放置了皇后result.append(board[:])sol_num += 1return

?對于情況①,如果固定皇后存在,則進行沖突判斷。

由于我們在解析initial_board[]的時候已經記錄過固定皇后的位置了,其實if下面那一行是多余的,但為了與情況②保存代碼對稱,我們依然保留。

if initial_board[row] != -1:  # 如果當前行已經有固定的皇后if is_valid(board, row, initial_board[row]):  # 檢查是否沖突board[row] = initial_board[row]spin(row + 1)board[row] = -1else:  # 如果沖突,則無解return

對于情況② ,如果該行為空,則正常進行列遍歷,找合適位置放入皇后。

else:  # 如果當前行沒有固定的皇后for col in range(n):if is_valid(board, row, col):  # 剪枝:只有有效位置才繼續board[row] = col  # 放置皇后spin(row + 1)  # 遞歸處理下一行board[row] = -1  # 回溯,撤銷放置

?四、輸出函數

你可能已經注意到了,我們找到解后并沒有立馬輸出,而是保存在result[]中。

因此輸出函數就是要從result[]中迭代輸出解(用上一節的prt()也是可以的,星馬想稍稍講講enumerate的用法)

首先先判斷有沒有解,直接看sol_num是否為零即可。

如果有解,就考慮如何從result中輸出解。

在使用enumerate前,最重要的事就是確定迭代對象的結構是什么樣的,即result是如何存儲解的狀態的?

還記得result是如何來的嗎?我們直接將board的全部狀態裝載進去了。

result.append(board[:])

其結構就是由board[]構成的解空間。?

result = [[1, 3, 0, 2],  # 解法 1[2, 0, 3, 1]   # 解法 2
]

?接下來,我們的輸出要求也是“解法X:解的結構”。

而result的存儲格式正好是“解法:解的結構”的鍵值對結構!

enumerate迭代器用于在遍歷容器時同時獲取元素的索引,也就是說他能同時返回我們想要的東西。

語法為:

for index, value in enumerate(iterable, start=0):

index是索引鍵,value是對應值,我們分別取idx和sol。

后面的邏輯和皇后問題一樣,先初始化 輸出行 為“...........”,從對應解取對應存放Q的位置,更改為'Q'

for idx, sol in enumerate(result):print(f"解法 {idx + 1}:")for r in range(n):line = ['.'] * nline[sol[r]] = 'Q'print(' '.join(line))print()

完整代碼:?

# 輸出結果
if sol_num == 0:print("無解")
else:for idx, sol in enumerate(result):print(f"解法 {idx + 1}:")for r in range(n):line = ['.'] * nline[sol[r]] = 'Q'print(' '.join(line))print()print(f"共找到 {sol_num} 種解法。")

至此,所有核心代碼結束,接下來的任務就是裝在一起就好啦~

我們將回溯函數、約束條件函數和執行邏輯全部封裝在solve_n_queens_with_given_board這個函數中,由于我們要獲取輸入n和殘局情況initial_board,因此要作為參數傳入。

def solve_n_queens_with_given_board(n, initial_board):def is_valid(board, row, col):#約束條件判斷def spin(row):#回溯函數#################################################################
調用solve_n_queens_with_given_board()后從這里開始執行,前面是函數聲明# 初始化board = [-1] * n  # 初始化當前棋盤狀態(-1 表示未放置皇后)result = []  # 存儲所有解sol_num = 0# 解析初始棋盤for r in range(n):# 檢查初始棋盤是否有沖突for r in range(n):# 開始回溯spin(0)# 輸出結果if sol_num == 0:無解else:輸出解# 示例調用
if __name__ == "__main__":n = int(input("請輸入棋盤大小 n:"))print("請輸入初始棋盤狀態('Q' 表示皇后,'.' 表示空位):")initial_board = [input().strip() for _ in range(n)]  # 接收一維數組solve_n_queens_with_given_board(n, initial_board)

完整代碼:

def solve_n_queens_with_given_board(n, initial_board):def is_valid(board, row, col):"""檢查當前位置 (row, col) 是否有效"""for i in range(row):  # 檢查當前行之前的行if board[i] == col or abs(i - row) == abs(board[i] - col):return Falsereturn Truedef spin(row):"""回溯函數"""nonlocal sol_numif row == n:  # 如果所有行都放置了皇后result.append(board[:])sol_num += 1returnif initial_board[row] != -1:  # 如果當前行已經有固定的皇后if is_valid(board, row, initial_board[row]):  # 檢查是否沖突board[row] = initial_board[row]spin(row + 1)board[row] = -1else:  # 如果沖突,則無解returnelse:  # 如果當前行沒有固定的皇后for col in range(n):if is_valid(board, row, col):  # 剪枝:只有有效位置才繼續board[row] = col  # 放置皇后spin(row + 1)  # 遞歸處理下一行board[row] = -1  # 回溯,撤銷放置# 初始化board = [-1] * n  # 當前棋盤狀態(-1 表示未放置皇后)result = []  # 存儲所有解sol_num = 0# 解析初始棋盤for r in range(n):try:c = initial_board[r].index('Q')  # 找到 'Q' 的列索引board[r] = c  # 固定該位置except ValueError:pass  # 如果該行沒有 'Q',跳過# 檢查初始棋盤是否有沖突for r in range(n):if board[r] != -1:  # 如果當前行有固定皇后if not is_valid(board, r, board[r]):print("無解")return# 開始回溯spin(0)# 輸出結果if sol_num == 0:print("無解")else:for idx, sol in enumerate(result):print(f"解法 {idx + 1}:")for r in range(n):line = ['.'] * nline[sol[r]] = 'Q'print(' '.join(line))print()print(f"共找到 {sol_num} 種解法。")# 示例調用
if __name__ == "__main__":n = int(input("請輸入棋盤大小 n:"))print("請輸入初始棋盤狀態('Q' 表示皇后,'.' 表示空位):")initial_board = [input().strip() for _ in range(n)]  # 接收一維數組solve_n_queens_with_given_board(n, initial_board)

小結:

殘局問題就是提前固定了幾個皇后,只要合理解決沖突就能簡單找到答案。本節還是希望諸位能體會回溯函數的變體和處理范式。

Ⅰ 剪枝就是提前終止,分為 可行 最優 啟發 對稱剪枝。

Ⅱ 一般對稱剪枝只處理第一行,因為深層剪枝會破壞對稱性。動態剪枝的開銷反而更大。

Ⅲ 接收二維數組可以用一維字符串數組:[input().strip() for _ in range(n)],n為接收批次數。

Ⅳ 從字符串找某字符索引用index('X')

Ⅴ Enumerate的用法:

? ? ? ? ① 確定存儲對象的結構。

? ? ? ? ② 根據for 索引, 對應值?in enumerate(result):獲取鍵值對。

寫在后面:

很開心你能耐著性子讀到這里,很榮幸能將我的三腳貓知識分享給大家。

星馬也是小白,因此更懂小白的心思,大佬認為一眼明白的代碼和思路可能在我們眼中就是鴻溝。這篇文章也還有很多不足之處,或是紕漏,希望你發現了及時在評論區提醒我呀~

(人工智能學院就是每周四五天滿課的啦,因此更新基本隨緣~)

星馬是剛入門的大菜比,有錯望指正,有項目可以帶帶我

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

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

相關文章

【玩泰山派】MISC(雜項)- 使用vscode遠程連接泰山派進行開發

文章目錄 前言流程1、安裝、啟動sshd2、配置一下允許root登錄3、vscode中配置1、安裝remote插件2、登錄 **注意** 前言 有時候要在開發板中寫一寫代碼,直接在終端中使用vim這種工具有時候也不是很方便。這里準備使用vscode去通過ssh遠程連接泰山派去操作&#xff0…

【VsCode】設置文件自動保存

目錄 一、前言 二、操作步驟 一、前言 VSCode中開啟自動保存功能可以通過訪問設置、修改settings.json文件、使用自動保存延遲功能來實現。這些方法能有效提升編程效率、避免數據丟失、實時同步更改。 二、操作步驟 在 Visual Studio Code (VS Code) 中設置自動保存功能非…

Adobe After Effects的插件--------Optical Flares之Options概述

Optical Flares插件的Options是對整個效果的組裝和設置。點擊該按鈕會彈出一個組裝室彈窗。 Options組裝室就是對每個【鏡頭對象】進行加工處理,再將其組裝在一起,拼湊成完整的光效。 接下來是我對組裝室的探索: 面板 面板中有預覽、堆棧、編輯和瀏覽按鈕,其作用是調節窗…

如何用 esProc 補充數據庫 SQL 的缺失能力

某些數據庫 SQL 缺失必要的能力,通常要編寫大段的代碼,才能間接實現類似的功能,有些情況甚至要改用存儲過程,連結構都變了。常見的比如:生成時間序列、保持分組子集、動態行列轉換、自然序號、相對位置、按序列和集合生…

迷你世界腳本腳本常見問題

腳本常見問題 彼得兔 更新時間: 2024-05-22 17:54:44 在查閱開發者學院中的腳本API時,若有任何問題或建議,歡迎通過問卷進行反饋!【點我填寫問卷】 1.Block中的data在什么地方使用 data使用有具體需求,此處不建議開發者使用。開發者盡可能使…

四、Appium Inspector

一、介紹 Appium Inspector 是一個用于移動應用自動化測試的圖形化工具,主要用于檢查和交互應用的 UI 元素,幫助生成和調試自動化測試腳本。類似于瀏覽器的F12(開發者工具),Appium Inspector 的主要作用包括:? 1.?檢查 UI 元素? …

android11通過白名單卸載安裝應用

目錄 1.源碼路徑: 2.準備文件package.conf: 3.安裝方法installPackagesLI 4.卸載方法deletePackageX 1.源碼路徑: frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java public static final String WHITELIST_PATH="/data/misc/pa…

qt mapFrom返回的QPoint和event->pos()區別和globalPos區別

mousePressEvent 和 eventFilter 里 event.pos 不一樣,一定要注意 eventFilter里event.pos 直接返回相對于label左上角的坐標,就不要再mapFrom mousePressEvent 里event.pos 返回是相對于窗口左上角的坐標,需要用mapFrom返回label左上角的…

Hadoop四 Hive語法

一 數據庫操作 Hive數據庫操作,與MySql有很多都是一致的 創建數據庫 create database if not exists myhive; use myhive;查看數據庫詳細信息 desc database myhive;數據庫本質上就是在HDFS之上的文件夾,是一個以.db結尾的目錄,默認存…

前端VUE框架理論與應用(10)

1、記住全局注冊的行為必須在根 Vue 實例 (通過 new Vue) 創建之前發生。 2、要注意,以 / 開頭的嵌套路徑會被當作根路徑。 這讓你充分的使用嵌套組件而無須設置嵌套的路徑。 3、注意:在 Vue 實例內部,你可以通過 $router 訪問路由實例。因此你可以調用 this.$router.push…

leetcode-單調棧26

關于單調棧的順序總結: 尋找右邊第一個比我大的:從左到右遍歷,棧單調遞減 尋找左邊第一個比我小的:從左到右遍歷,棧單調遞增 尋找右邊第一個比我小的:從右到左遍歷,棧單調遞增 尋找左邊第一個比…

Linux:安裝 CentOS 7(完整教程)

文章目錄 一、簡介二、安裝 CentOS 72.1 虛擬機配置2.2 安裝CentOS 7 三、連接遠程服務器(擴展)3.1 獲取虛擬機 IP 地址3.2 連接遠程服務器 四、結語 一、簡介 CentOS(Community ENTerprise Operating System)是一個基于 Linux 的…

Nautilus 正式發布:為 Sui 帶來可驗證的鏈下隱私計算

作為 Sui 安全工具包中的強大新成員,Nautilus 現已上線 Sui 測試網。它專為 Web3 開發者打造,支持保密且可驗證的鏈下計算。Nautilus 應用運行于開發者自主管理的可信執行環境(Trusted Execution Environment,TEE)中&a…

Git完全指南:從入門到精通版本控制 ------- Git 工作流程 (3)

Git工作流程完全指南:從入門到高效協作 引言 Git作為分布式版本控制系統的行業標準,其高效的分支管理能力是團隊協作的基石。本文將深入解析標準Git工作流程,助你掌握從代碼提交到團隊協作的全鏈路實踐。 一、Git核心概念速覽 三大工作區域 …

Distortion, Animation Raymarching

這節課的主要目的是對uv進行操作,實現一些動畫的效果,實際就是采樣的動畫 struct texDistort {float2 texScale(float2 uv, float2 scale){float2 texScale (uv - 0.5) * scale 0.5;return texScale;}float2 texRotate(float2 uv, float angle){float…

《vue3學習手記3》

標簽的ref屬性 vue3和vue2中的ref屬性: 用在普通DOM標簽上,獲取的是DOM節點 ref用在組件標簽上,獲取的是組件實例對象 區別在于: 1.vue3中person子組件中的數據父組件App不能直接使用,需要引入并使用defineExpose才可…

List基礎與難度題

1. 向 ArrayList 中添加元素并打印 功能描述: 程序創建一個空的 ArrayList 集合,用于存儲字符串類型的元素。向該 ArrayList 中依次添加指定的字符串元素。使用增強型 for 循環遍歷 ArrayList 中的所有元素,并將每個元素打印輸出到控制臺。 …

樓宇自控系統如何為現代建筑打造安全、舒適、節能方案

在科技飛速發展的當下,現代建筑對功能和品質的要求日益提升。樓宇自控系統作為建筑智能化的核心技術,宛如一位智慧的“管家”,憑借先進的技術手段,為現代建筑精心打造安全、舒適、節能的全方位解決方案,讓建筑真正成為…

綠算輕舟系列FPGA加速卡:驅動數字化轉型的核心動力【2】

工業與醫療:精準化的幕后推手 在工業4.0與智慧醫療領域,綠算輕舟FPGA加速卡通過實時信號處理與高精度控制,推動關鍵場景的技術升級。 工業自動化:在機器視覺質檢中,實現亞像素級缺陷檢測,產線檢測速度大幅…

uniapp-商城-22-頂部模塊

這里其實很復雜.我們在前面已經說了這個組件 shop-headbar ,這里來繼續說。 該組件實現一個高度的顯示以及圖片展示,包含logo 名稱 后臺管理以及避讓 導航欄 和 手機的狀態欄。 1 整體 代碼如下: <template><view class="headr" :style="{ hei…