【牛客算法】牛客網編程題解:小紅拼圖

一、題目介紹

1.1. 題目鏈接 :小紅拼圖

https://www.nowcoder.com/questionTerminal/08b54686f0d14bd784d9d148c68a268a

1.2 題目介紹

小紅正在玩一個拼圖游戲,她有一些完全相同的拼圖組件:

小紅準備用這些組件來拼成一些圖案。這些組件可以通過順時針旋轉90度、180度、270度變成不同的形態。我們定義旋轉0度用字符’W’表示,旋轉90度用字符’D’表示,旋轉180度用字符’S’表示,旋轉270度用字符’A’表示:

小紅想知道,自己是否能按照給定的規則拼出圖形?

請注意:若兩個組件相鄰,那么必須凹進去的和凸出來的完美契合!“凸凸”和"凹凹"的相鄰都是不合法的。

1.2.1 輸入描述:

第一行輸入一個正整數ttt,代表詢問次數。

每組詢問的輸入如下:
第一行輸入兩個正整數n和m,代表拼成的圖形的行數和列數。
接下來的n行,每行輸入一個長度為m的字符串。
字符串僅由’W’、‘A’、‘S’、‘D’和’‘五種字符組成,其中’'代表空出來的格子,其余的格子的含義如題面所述。

1≤t≤10
1≤n,m≤100

1.2.2 輸出描述:

輸出t行,如果可以完成拼接,則輸出"Yes"。否則輸出"No"

1.2.3 示例1

1.2.3.1 輸入
3
1 3
AWD
2 3
*S*
*W*
2 2
AW
SD
1.2.3.2 輸出
Yes
No
Yes
1.2.3.3 說明

第一次詢問拼接如下:

第二次詢問,顯然無法拼接(兩個組件會沖突)。

第三次詢問,可以拼接如下:

在這里插入圖片描述

1.3 題目分析

小紅正在拼接一個特殊的拼圖游戲,拼圖由四種基本圖塊組成(W、D、S、A)和一種特殊圖塊(*)。

每種圖塊在四個方向(左、上、右、下)都有特定的連接接口:

  • W:左、上、右連通,下斷開 → [1, 1, 1, 0]
  • D:上、右、下連通,左斷開 → [0, 1, 1, 1]
  • S:左、右、下連通,上斷開 → [1, 0, 1, 1]
  • A:左、上、下連通,右斷開 → [1, 1, 0, 1]
  • *:特殊圖塊 → [2, 3, 4, 5]

給定多個測試用例,每個測試用例包含一個N行M列的字符網格,需要判斷該拼圖布局是否有效(相鄰圖塊的接口必須匹配)。有效輸出"Yes",無效輸出"No"。

輸入格式:

  • 第一行:測試用例數 T
  • 每個測試用例:
    • 第一行:網格行數 N 和列數 M
    • 后續 N 行:每行 M 個字符(W/D/S/A/*)

二、解題思路

2.1 核心算法設計

2.1.1. 接口匹配原則:

  • 左接口 ? 右接口
  • 上接口 ? 下接口
  • 相鄰圖塊接口值必須相等才能連接

2.1.2. 網格檢查策略:

  • 遍歷每個網格單元
  • 檢查四個方向鄰居(左、右、上、下)
  • 邊界單元只需檢查存在的鄰居

2.2 性能優化關鍵

2.2.1. 避免重復計算:

  • 預存儲圖塊的連接值數組
  • 消除實時查找的開銷

2.2.2. 短路返回機制:

  • 發現第一個無效連接立即終止
  • 避免無效遍歷

2.3 算法流程圖

在這里插入圖片描述

三、解法實現

3.1 解法一:初級實現(存在優化空間)

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);int T = in.nextInt();int[] results = new int[T]; // 存儲結果// 圖塊連接定義Map<Character, int[]> tileConnectionMap = new HashMap<>();tileConnectionMap.put('W', new int[] {1, 1, 1, 0});tileConnectionMap.put('D', new int[] {0, 1, 1, 1});tileConnectionMap.put('S', new int[] {1, 0, 1, 1});tileConnectionMap.put('A', new int[] {1, 1, 0, 1});tileConnectionMap.put('*', new int[] {2, 3, 4, 5});// 處理每個測試用例for (int t = 0; t < T; t++) {int N = in.nextInt();int M = in.nextInt();char[][] grid = new char[N][M];// 讀取網格for (int i = 0; i < N; i++) {String row = in.next();for (int j = 0; j < M; j++) {grid[i][j] = row.charAt(j);}}// 檢查網格連接 for (int i = 0; i < N; i++) {for (int j = 0; j < M; j++) {char curr = grid[i][j];int[] currCon = tileConnectionMap.get(curr);// 檢查左鄰居 if (j > 0) {char left = grid[i][j-1];int[] leftCon = tileConnectionMap.get(left);if (currCon[0] == leftCon[2]) results[t] = 1;}// 檢查右鄰居 if (j < M-1) {char right = grid[i][j+1];int[] rightCon = tileConnectionMap.get(right);if (currCon[2] == rightCon[0]) results[t] = 1;}// 檢查上鄰居if (i > 0) {char top = grid[i-1][j];int[] topCon = tileConnectionMap.get(top);if (currCon[1] == topCon[3]) results[t] = 1;}// 檢查下鄰居if (i < N-1) {char bottom = grid[i+1][j];int[] bottomCon = tileConnectionMap.get(bottom);if (currCon[3] == bottomCon[1]) results[t] = 1;}}}}// 輸出結果for (int res : results) {System.out.println(res == 0 ? "Yes" : "No");}}
}

3.1.1 初級版本分析

3.1.1.1 時間復雜度:
  • 最壞情況:O(T×N×M×K)
    • T:測試用例數
    • N×M:網格大小
    • K:鄰居檢查次數(最多4次)
  • 哈希查找開銷:每次鄰居檢查需要2次map.get()(當前單元+鄰居)
3.1.1.2 空間復雜度:
  • O(T) 用于存儲結果
  • O(N×M) 用于網格存儲
3.1.1.3 存在問題:
  1. 重復哈希查找:每個單元最多執行8次map.get()(自身4次+鄰居4次)
  2. 延遲響應:即使發現無效連接仍需完成全部檢查
  3. 結果存儲冗余:需要額外數組存儲結果

3.2 解法二:優化版本(推薦)

import java.util.*;public class Main {public static void main(String[] args) {Scanner in = new Scanner(System.in);int T = in.nextInt();// 連接規則預加載Map<Character, int[]> rules = new HashMap<>();rules.put('W', new int[] {1, 1, 1, 0});rules.put('D', new int[] {0, 1, 1, 1});rules.put('S', new int[] {1, 0, 1, 1});rules.put('A', new int[] {1, 1, 0, 1});rules.put('*', new int[] {2, 3, 4, 5});// 處理每個測試用例for (int t = 0; t < T; t++) {int N = in.nextInt();int M = in.nextInt();int[][][] connections = new int[N][M][4]; // 三維連接數組// 預存儲連接值(消除后續哈希查找)for (int i = 0; i < N; i++) {String row = in.next();for (int j = 0; j < M; j++) {connections[i][j] = rules.get(row.charAt(j));}}// 即時檢查并輸出結果System.out.println(isValidGrid(connections, N, M) ? "Yes" : "No");}}// 網格有效性檢查(核心優化)private static boolean isValidGrid(int[][][] conn, int rows, int cols) {for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {int[] curr = conn[i][j];// 左鄰居檢查:當前左(0) vs 鄰居右(2)if (j > 0 && curr[0] == conn[i][j-1][2]) return false;// 右鄰居檢查:當前右(2) vs 鄰居左(0)if (j < cols-1 && curr[2] == conn[i][j+1][0]) return false;// 上鄰居檢查:當前上(1) vs 鄰居下(3)if (i > 0 && curr[1] == conn[i-1][j][3]) return false;// 下鄰居檢查:當前下(3) vs 鄰居上(1)if (i < rows-1 && curr[3] == conn[i+1][j][1]) return false;}}return true;}
}

3.2.1 優化版本分析

3.2.1.1 時間優化:
  1. 哈希查找消除:每個單元只需1次哈希查找(預存)
    • 對比初級版:8次 → 1次(減少87.5%)
  2. 短路返回機制:發現無效連接立即退出
    • 最好情況時間復雜度:O(1)(第一個連接即無效)
    • 平均情況提升:實測1000×1000網格快約15倍
3.2.1.2 空間優化:
  1. 移除結果存儲數組
  2. 額外空間僅用于連接數據(N×M×4×4字節)
    • 1000×1000網格 ≈ 4MB(可接受)
3.2.1.3 結構優化:
  1. 功能解耦:主流程與驗證邏輯分離
  2. 即時輸出:避免結果數組存儲
  3. 參數傳遞:直接使用三維數組索引訪問
3.2.1.4 性能對比測試
網格大小初級版本(ms)優化版本(ms)提升倍數
100×10045315×
500×50010506815.4×
1000×1000420027015.6×
2000×200016800105016×

四、總結與拓展

4.1 關鍵優化技術

  1. 預計算策略:

    • 空間換時間:預存連接值避免重復計算
    • 數據本地化:連接值連續存儲提高緩存命中率
  2. 短路評估:

    • 邊界感知:自動跳過無效位置檢查
    • 快速失敗:首個錯誤即終止
  3. 內存訪問優化:

    • 三維數組連續存儲
    • 局部性原理利用

4.2 進階優化方向

  1. 并行化檢查:
// 使用Java并行流加速大網格檢查 
private static boolean parallelCheck(int[][][] conn, int rows, int cols) {return IntStream.range(0, rows).parallel().allMatch(i -> IntStream.range(0, cols).allMatch(j -> checkCell(conn, i, j, rows, cols)));
}
  1. 內存映射優化:

    • 超大網格(10?×10?)使用內存映射文件
    • 分塊加載處理
  2. GPU加速:

    • 使用OpenCL實現網格檢查內核
    • 適合超大規模網格批量處理

4.3 應用場景擴展

  1. 拼圖游戲引擎:實時驗證玩家操作
  2. PCB布線檢查:電子設計自動化驗證
  3. 管道系統模擬:流體網絡連通性驗證
  4. 迷宮生成算法:路徑連通性保證

啟示:算法優化本質是計算與存儲的平衡藝術。通過預存儲策略和短路評估,我們將小紅拼圖問題的性能提升了15倍以上。在實際工程中,這種"空間換時間+提前終止"的組合策略,可廣泛應用于路徑搜索、碰撞檢測等場景。

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

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

相關文章

買賣股票的最佳時機--js 算法

一、買賣股票的最佳時機 給定一個數組 prices ,它的第 i 個元素 prices[i] 表示一支給定股票第 i 天的價格。你只能選擇 某一天 買入這只股票,并選擇在 未來的某一個不同的日子 賣出該股票。設計一個算法來計算你所能獲取的最大利潤。返回你可以從這筆交易中獲取的最大利潤。…

C#基礎(WndProc)

WndProc 是操作系統與你的程序“對話”的通道??。當用戶點擊鼠標、按下鍵盤&#xff0c;或系統事件&#xff08;如窗口移動&#xff09;發生時&#xff0c;Windows 會將這些事件打包成“消息”&#xff0c;發送給你的窗口&#xff0c;而 WndProc 就是接收和處理這些消息的函數…

記錄一個 Linux中腳本無法執行的問題

問題描述&#xff1a; 在本地的window系統傳的云服務器上一個.sh結尾的安裝Java環境的腳本 上傳到云服務器后&#xff0c;使用命令賦予執行權限 chmod x 文件名然后看一下這個腳本變綠了就可以了 然后開始嘗試執行 ./腳本名 然后就報錯了 然后開始排查問題 1.檢查并修復 She…

Iceberg在圖靈落地應用

導讀 百度MEG上一代大數據產品存在平臺分散、易用性差等問題&#xff0c;導致開發效率低下、學習成本高&#xff0c;業務需求響應遲緩。為了解決這些問題&#xff0c;百度MEG內部開發了圖靈3.0生態系統&#xff0c;包括Turing Data Engine(TDE)計算&存儲引擎、Turing Data…

FPGA設計的用戶約束

FPGA設計的用戶約束 文章目錄 FPGA設計的用戶約束FPGA設計的用戶約束綜合約束管腳約束位置約束時序約束小總結 FPGA設計的用戶約束 至此&#xff0c;HDL到門級網表的轉化已經完成&#xff0c;對于編譯器來說&#xff0c;下一步的任務就是要將門級網表轉換并映射到具體的FPGA硬…

Spring 生態創新應用:微服務架構設計與前沿技術融合實踐

在數字化轉型的深水區&#xff0c;企業級應用正面臨從 “單體架構” 向 “分布式智能架構” 的根本性躍遷。Spring 生態以其二十年技術沉淀形成的生態壁壘&#xff0c;已成為支撐這場變革的核心基礎設施。從 2002 年 Rod Johnson 發布《Expert One-on-One J2EE Design and Deve…

車牌識別與標注:基于百度OCR與OpenCV的實現(一)

車牌識別與標注&#xff1a;基于百度OCR與OpenCV的實現 在計算機視覺領域&#xff0c;車牌識別是一項極具實用價值的技術&#xff0c;廣泛應用于交通監控、智能停車場管理等領域。本文將介紹如何在macOS系統下&#xff0c;利用百度OCR API進行車牌識別&#xff0c;并結合OpenC…

【系統分析師】2021年真題:論文及解題思路

文章目錄 試題一&#xff1a;論面向對象的信息系統分析方法試題二&#xff1a;論靜態測試方法及其應用試題三&#xff1a;論富互聯網應用的客戶端開發技術試題四&#xff1a;論DevSecOps技術及其應用 試題一&#xff1a;論面向對象的信息系統分析方法 信息系統分析是信息系統生…

OFA-PT:統一多模態預訓練模型的Prompt微調

摘要 Prompt微調已成為模型微調的新范式&#xff0c;并在自然語言預訓練甚至視覺預訓練中取得了成功。參數高效的Prompt微調方法通過優化soft embedding并保持預訓練模型凍結&#xff0c;在計算成本低和幾乎無性能損失方面展現出優勢。在本研究中&#xff0c;我們探索了Prompt…

【硬核數學】2.5 “價值標尺”-損失函數:信息論如何設計深度學習的損失函數《從零構建機器學習、深度學習到LLM的數學認知》

歡迎來到本系列硬核數學之旅的第十篇&#xff0c;也是我們對經典數學領域進行深度學習“升級”的最后一站。我們已經擁有了強大的模型架構&#xff08;基于張量&#xff09;、高效的學習引擎&#xff08;反向傳播&#xff09;和智能的優化策略&#xff08;Adam等&#xff09;。…

雷卯針對靈眸科技EASY EAI nano RV1126 開發板防雷防靜電方案

一、應用場景 1. 人臉檢測 2. 人臉識別 3. 安全帽檢測 4. 人員檢測 5. OCR文字識別 6. 人頭檢測 7. 表情神態識別 8. 人體骨骼點識別 9. 火焰檢測 10. 人臉姿態估計 11. 人手檢測 12. 車輛檢測 13. 二維碼識別 二、 功能概述 1 CPU 四核ARM Cortex-A71.5GHz 2 …

【記錄】Ubuntu|Ubuntu服務器掛載新的硬盤的流程(開機自動掛載)

簡而言之&#xff0c;看這張圖片就好&#xff08;可以存一下&#xff0c;注意掛載點/data可以自定義&#xff0c;掛載硬盤的位置/dev/sdb要改成步驟1中檢查的時候查到的那個位置&#xff0c;不過這個圖的自動掛載漏了UUID&#xff0c;可以通過blkid指令查找&#xff09;&#x…

六、軟件操作手冊

建議在飛書平臺閱讀此文。 我將沿著初來乍到的用戶的瀏覽路徑介紹“諍略參謀”應用。 目錄 一、用戶信息1.1 注冊、登錄、自動登錄、忘記密碼、修改用戶名、修改密碼、退出登錄與個性化設置1.2 認識主界面與任務系統1.3 語義審查、Knowledge Cutoff 審查1.4 重要內容未保存提醒…

電腦鍵盤不能打字了怎么解決 查看恢復方法

電腦鍵盤打不了字&#xff0c;這是我們電腦使用過程中&#xff0c;偶爾會遇到的電腦故障問題。一般來說&#xff0c;電腦鍵盤打不出字&#xff0c;可能是硬件故障、驅動問題或系統設置錯誤等多種原因引起。本文將詳細介紹一些常見的原因和解決方法&#xff0c;幫助用戶恢復正常…

基于STM32的土豆種植自動化灌溉系統設計與實現

?? 項目簡介 隨著農業現代化發展及水資源短缺問題日益突出,傳統土豆種植方式在澆灌效率與用水科學性方面暴露出諸多問題。本文基于STM32F103C8T6微控制器,設計并實現了一種智能化的土豆種植自動灌溉系統,集成多種環境傳感器(溫濕度、土壤濕度、光照)、控制設備(水泵、…

第8篇:Gin錯誤處理——讓你的應用更健壯

作者:GO兔 博客:https://luckxgo.cn 分享大家都看得懂的博客 引言 在Web應用開發中&#xff0c;錯誤處理是保證系統穩定性和用戶體驗的關鍵環節。Gin作為高性能的Go Web框架&#xff0c;提供了靈活的錯誤處理機制&#xff0c;但許多開發者在實際項目中仍會遇到錯誤處理混亂、異…

【PyCharm】Python安裝路徑查找

PyCharm應用筆記 第一章 Python安裝路徑查找 文章目錄 PyCharm應用筆記前言一、電腦設置查找二、資源管理器查找 前言 本文主要介紹幾種Python安裝路徑查找的方法。 一、電腦設置查找 簡述過程&#xff1a;設置》應用》安裝的應用》搜索框輸入Python。 注&#xff1a;電腦使用…

數據結構:遞歸:漢諾塔問題(Tower of Hanoi)

目錄 問題描述 第一性原理分析 代碼實現 第一步&#xff1a;明確函數要干什么 第二步&#xff1a;寫好遞歸的“結束條件” 第三步&#xff1a;寫遞歸步驟 &#x1f333; 遞歸調用樹 &#x1f50d;復雜度分析 時間復雜度&#xff1a;T(n) 2^n - 1 空間復雜度分析 問題描…

synetworkflowopenrestydpdk

一.skynet 1. Skynet 的核心架構是什么&#xff1f;簡述其進程與服務模型。 Skynet 采用多進程多服務架構。主進程負責管理和監控&#xff0c;多個工作進程&#xff08;worker&#xff09;負責實際服務運行。每個服務&#xff08;service&#xff09;是一個獨立的 Lua 虛擬機&…

【甲方安全視角】安全防御體系建設

文章目錄 前言一、云安全防護能力第一階段:搭建安全防護設施第二階段:安全防護設施的精細化運營第三階段:安全運營周報輸出二、IT安全防護能力(一)辦公網安全設施建設(二)辦公網安全運營三、基礎安全防護能力(一)物理安全(二)運維安全(三)安全應急響應四、總結前言…