[藍橋杯]密文搜索

密文搜索

題目描述

福爾摩斯從 X 星收到一份資料,全部是小寫字母組成。

他的助手提供了另一份資料:許多長度為 8 的密碼列表。

福爾摩斯發現,這些密碼是被打亂后隱藏在先前那份資料中的。

請你編寫一個程序,從第一份資料中搜索可能隱藏密碼的位置。要考慮密碼的所有排列可能性。

輸入描述

輸入第一行:一個字符串?ss,全部由小寫字母組成,長度小于 1024*1024。

緊接著一行是一個整數?nn,表示以下有?nn?行密碼,1≤n≤10001≤n≤1000。

緊接著是?nn?行字符串,都是小寫字母組成,長度都為 8。

輸出描述

輸出一個整數, 表示每行密碼的所有排列在?ss?中匹配次數的總和。

輸入輸出樣例

示例

輸入

aaaabbbbaabbcccc
2
aaaabbbb
abcabccc

輸出

4

運行限制

  • 最大運行時間:3s
  • 最大運行內存: 512M

總通過次數: 821??|??總提交次數: 975??|??通過率: 84.2%

難度: 困難???標簽: 2015, 國賽

算法思路:滑動窗口 + 頻率哈希

本問題要求在長字符串中高效搜索多個長度為8的密碼的所有排列出現的總次數。核心挑戰在于避免枚舉所有排列組合(8! = 40320),采用??字符頻率統計+滑動窗口優化??策略:

 

圖片

代碼

 

graph TD A[輸入主串s和密碼列表] --> B[密碼預處理] B --> C[頻率向量→字符串<br>存入哈希表] C --> D[初始化窗口0-7] D --> E[更新頻率字符串<br>查詢哈希表] E --> F[滑動窗口:移左字符+移右字符] F --> G[更新兩個字符頻率] G --> E E --> H[累加匹配次數] H --> I[輸出總和]

輸入主串s和密碼列表

密碼預處理

頻率向量→字符串
存入哈希表

初始化窗口0-7

更新頻率字符串
查詢哈希表

滑動窗口:移左字符+移右字符

更新兩個字符頻率

累加匹配次數

輸出總和

算法步驟

  1. ??頻率向量表示排列??:兩個字符串互為排列當且僅當字符頻率相同。將每個密碼表示為26維頻率向量(a~z的計數)。
  2. ??密碼預處理??:計算每個密碼的頻率向量,轉換為26字符的字符串(如?"400400..."),存入哈希表記錄出現次數。
  3. ??滑動窗口掃描??:
    • 初始化窗口(0~7)的頻率向量
    • 窗口右移時,僅更新移出字符(左邊界)和移入字符(右邊界)的頻率
    • 實時更新頻率字符串,查詢哈希表累加匹配次數
  4. ??優化關鍵??:維護動態頻率字符串,避免每次重新生成。

    算法思路:滑動窗口 + 頻率哈希

    本問題要求在長字符串中高效搜索多個長度為8的密碼的所有排列出現的總次數。核心挑戰在于避免枚舉所有排列組合(8! = 40320),采用??字符頻率統計+滑動窗口優化??策略:

  5. ??頻率向量表示排列??:兩個字符串互為排列當且僅當字符頻率相同。將每個密碼表示為26維頻率向量(a~z的計數)。
  6. ??密碼預處理??:計算每個密碼的頻率向量,轉換為26字符的字符串(如?"400400..."),存入哈希表記錄出現次數。
  7. ??滑動窗口掃描??:
    • 初始化窗口(0~7)的頻率向量
    • 窗口右移時,僅更新移出字符(左邊界)和移入字符(右邊界)的頻率
    • 實時更新頻率字符串,查詢哈希表累加匹配次數
  8. ??優化關鍵??:維護動態頻率字符串,避免每次重新生成。
  9. ??密碼預處理??(O(n×26))
    • 對每個密碼,統計a~z頻率(26維數組)
    • 頻率數組轉為26字符字符串(如?[4,4,0,...] → "440..."
    • 哈希表記錄頻率字符串出現次數
  10. ??窗口初始化??(O(26))
    • 計算主串前8字符的頻率數組
    • 生成初始頻率字符串
  11. ??滑動窗口??(O(|s|×2))
    • 移出左邊界字符:對應頻率減1,更新頻率字符串
    • 移入右邊界字符:對應頻率加1,更新頻率字符串
    • 查詢哈希表累加匹配次數
  12. ??結果輸出??:總匹配次數

算法步驟

  1. ??密碼預處理??(O(n×26))
    • 對每個密碼,統計a~z頻率(26維數組)
    • 頻率數組轉為26字符字符串(如?[4,4,0,...] → "440..."
    • 哈希表記錄頻率字符串出現次數
  2. ??窗口初始化??(O(26))
    • 計算主串前8字符的頻率數組
    • 生成初始頻率字符串
  3. ??滑動窗口??(O(|s|×2))
    • 移出左邊界字符:對應頻率減1,更新頻率字符串
    • 移入右邊界字符:對應頻率加1,更新頻率字符串
    • 查詢哈希表累加匹配次數
  4. ??結果輸出??:總匹配次數

代碼實現(C++)

#include <iostream>
#include <vector>
#include <unordered_map>
using namespace std;int main() {ios::sync_with_stdio(false);cin.tie(0);string s;cin >> s;int n;cin >> n;// 1. 密碼預處理:頻率數組→字符串unordered_map<string, int> count_map;for (int i = 0; i < n; i++) {string pwd;cin >> pwd;vector<int> freq(26, 0);for (char c : pwd) freq[c - 'a']++;string key(26, '0');for (int j = 0; j < 26; j++) key[j] = '0' + freq[j]; // 頻率轉字符count_map[key]++;}// 2. 處理邊界:主串長度不足8int len = s.size();if (len < 8) {cout << 0 << endl;return 0;}// 3. 初始化窗口頻率vector<int> win_freq(26, 0);string win_key(26, '0');for (int i = 0; i < 8; i++) {int idx = s[i] - 'a';win_freq[idx]++;win_key[idx] = '0' + win_freq[idx]; // 動態更新}// 4. 滑動窗口掃描long long total = count_map[win_key]; // 初始窗口匹配for (int i = 1; i <= len - 8; i++) {// 移出左邊界字符int idx_out = s[i-1] - 'a';win_freq[idx_out]--;win_key[idx_out] = '0' + win_freq[idx_out];// 移入右邊界字符int idx_in = s[i+7] - 'a';win_freq[idx_in]++;win_key[idx_in] = '0' + win_freq[idx_in];total += count_map[win_key]; // 查詢累加}cout << total << endl;return 0;
}

代碼解析

  1. ??密碼預處理??(L15-25)
    • freq[26]:存儲a~z頻率(freq[0]=a
    • key:26字符字符串(key[0]='4'表示a出現4次)
    • count_map:記錄頻率字符串出現次數
  2. ??窗口初始化??(L35-41)
    • win_freq:窗口頻率數組
    • win_key:動態更新的頻率字符串
  3. ??滑動窗口??(L44-57)
    • ??移出字符??:左邊界s[i-1]頻率減1,更新win_key對應位置
    • ??移入字符??:右邊界s[i+7]頻率加1,更新win_key對應位置
    • ??查詢累加??:直接訪問count_map
  4. ??復雜度分析??
    • 時間:O(n×26 + |s|×2) ≈ O(26,000 + 2,000,000) = 2.03e6(1e6主串)
    • 空間:O(n×26) ≈ 26,000(1000密碼)

實例驗證

??輸入??:

aaaabbbbaabbcccc
2
aaaabbbb    → 頻率字符:'4','4','0',...(24個0)
abcabccc    → 頻率字符:'2','2','4','0',...(23個0)

??執行過程??:

窗口位置子串頻率字符串匹配密碼累加值
0-7aaaabbbb44000...密碼11
1-8aaabbbba44000...密碼12
2-9aabbbbaa44000...密碼13
8-15aabbcccc22400...密碼24

??輸出??:4??

注意事項

  1. ??邊界處理??:
    • 主串長度?<8?時直接返回0
    • 窗口右邊界?i+7?需滿足?i ≤ len-8
  2. ??頻率轉換??:
    • 密碼字符必須小寫(c-'a'索引0~25)
    • 頻率范圍0~8('0'+freq?不會溢出)
  3. ??哈希沖突??:
    • 不同頻率數組可能生成相同字符串(概率極低)
    • 可改用vector作為鍵(需自定義哈希)

多方位測試點

??測試類型????輸入樣例????預期輸出????驗證要點??
主串不足8字符"abc", 1, "abcdefgh"0邊界處理
單密碼全匹配"aaaaaaaa", 1, "aaaaaaaa"9重疊窗口計數
多密碼相同頻率兩密碼頻率相同雙倍計數哈希表累計驗證
零匹配"abcdefgh", 1, "zzzzzzzz"0無匹配處理
最大規模1e6長度主串, 1000密碼約1e6次操作時間效率(<0.5s)
特殊字符分布"abcdabcd", 1, "aabbccdd"1頻率計算正確性

優化建議

  1. ??向量哈希替代字符串??:
    struct VectorHash {size_t operator()(const vector<int>& v) const {size_t seed = 0;for (int x : v) seed ^= hash<int>()(x) + 0x9e3779b9 + (seed<<6) + (seed>>2);return seed;}
    };
    unordered_map<vector<int>, int, VectorHash> count_map; // 避免字符串轉換
  2. ??并行化處理??:
    #pragma omp parallel for reduction(+:total)
    for (int i = 0; i <= len-8; i++) {// 各窗口獨立計算
    }
  3. ??內存優化??:
    • 鏈式前向星存儲頻率表(減少vector開銷)
    • 預分配哈希表桶數量:count_map.reserve(n)

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

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

相關文章

打卡第36天:模型可視化以及推理

知識點回顧&#xff1a; 1.三種不同的模型可視化方法&#xff1a;推薦torchinfo打印summary權重分布可視化 2.進度條功能&#xff1a;手動和自動寫法&#xff0c;讓打印結果更加美觀 3.推理的寫法&#xff1a;評估模式 作業&#xff1a;調整模型定義時的超參數&#xff0c;對…

8天Python從入門到精通【itheima】-68(元組)

目錄 65節——元組的定義和操作 1.學習目標 2.為什么要學習元組 3.元組的定義 4.定義元組的注意事項 5.元組的嵌套 6.元組的相關操作 【1】index方法 【2】count方法 【3】len方法 7.元組的遍歷 【1】while循環進行元組的遍歷 【2】for循環進行元組的變量 Python …

鏈表題解——環形鏈表【LeetCode】

141. 環形鏈表 方法一 核心思想&#xff1a; 使用一個集合 seen 來記錄已經訪問過的節點。遍歷鏈表&#xff0c;如果當前節點已經存在于集合中&#xff0c;說明鏈表存在環&#xff1b;否則&#xff0c;將當前節點添加到集合中&#xff0c;繼續遍歷。如果遍歷結束&#xff08;h…

【免費數據】1980-2022年中國2384個站點的水質數據

水&#xff0c;是生命之源&#xff0c;關乎著地球上每一個生物的生存與發展。健康的水生生態系統維持著整個水生態的平衡與活力&#xff1b;更是確保人類能持續獲得清潔水源的重要保障。水質數據在水質研究、海洋生物量測算以及生物多樣性評估等諸多關鍵領域都扮演著舉足輕重的…

分享推薦高精度磁阻式磁編碼器芯片

磁編碼器其通過感應旋轉磁場來實現角度、轉速的測量&#xff0c;因此&#xff0c;相較于傳統的光編碼器&#xff0c;磁編碼器對粉塵、污垢和油脂等污染物有很強的耐受性&#xff0c;即使在較為惡劣的環境中仍能夠保持高分辨率與檢測精度&#xff0c;安裝和維護簡捷方便&#xf…

Spring AI 項目實戰(四):Spring Boot + AI + DeepSeek 超參數優化——智能化機器學習平臺(附完整源碼)

系列文章 序號文章名稱1Spring AI 項目實戰&#xff08;一&#xff09;&#xff1a;Spring AI 核心模塊入門2Spring AI 項目實戰&#xff08;二&#xff09;&#xff1a;Spring Boot AI DeepSeek 深度實戰&#xff08;附完整源碼&#xff09;3Spring AI 項目實戰&#xff08…

高效VLM:VisionZip

論文&#xff1a;[2412.04467] VisionZip: Longer is Better but Not Necessary in Vision Language Models github&#xff1a;https://github.com/dvlab-research/VisionZip LLaVA論文&#xff1a;https://arxiv.org/abs/2310.03744 LLaVA倉庫&#xff1a;https://github.…

華為設備OSPF配置與實戰指南

一、基礎配置架構 sysname HUAWEI-ABR ospf 100 router-id 1.1.1.1area 0.0.0.0network 10.1.1.0 0.0.0.255 # 將接口加入區域0 interface GigabitEthernet0/0/1ospf enable 100 area 0.0.0.0 # 華為支持點分十進制區域號bandwidth-reference 10000 # 設置10Gbps參考帶寬…

區塊鏈架構深度解析:從 Genesis Block 到 Layer 2

# 區塊鏈架構深度解析&#xff1a;從 Genesis Block 到 Layer 2 目錄 一、Genesis Block&#xff1a;區塊鏈的起點 二、Layer 0&#xff1a;區塊鏈的底層網絡架構 三、Layer 1&#xff1a;核心協議層 &#x1f680; 四、Layer 2&#xff1a;擴展性解決方案 五、未來展望&a…

【位運算】丟失的數字(easy)

34. 丟失的數字&#xff08;easy&#xff09; 題?描述&#xff1a;方法一&#xff1a;排序解法&#xff08;位運算&#xff09;&#xff1a;C 算法代碼&#xff1a;Java 算法代碼&#xff1a; 題?鏈接&#xff1a; 268. 丟失的數字 題?描述&#xff1a; 給定?個包含 [0, n…

如何通過RL真正提升大模型的推理能力?NVIDIA提出長期強化學習訓練框架ProRL

原文&#xff1a;https://mp.weixin.qq.com/s/QLFKvb8Ol3CX9uWKBXSrow 論文&#xff1a;ProRL: Prolonged Reinforcement Learning Expands Reasoning Boundaries in Large Language Models Abs&#xff1a;https://arxiv.org/abs/2505.24864 權重下載&#xff1a;https://hugg…

ORM 框架的優缺點分析

ORM 框架的優缺點分析 一、ORM 框架概述 ORM(Object-Relational Mapping)是一種將關系型數據庫與面向對象編程進行映射的技術框架。它通過將數據庫表映射為編程語言中的類,將記錄映射為對象,將字段映射為屬性,實現了用面向對象的方式操作數據庫。 核心價值:ORM 在數據庫和…

1. 數據庫基礎

1.1 什么是數據庫 ? mysql 本質是一種網絡服務, 是基于 C(mysql) S(mysqld)的 網絡服務. 存儲數據用文件就可以了&#xff0c;為什么還要弄個數據庫&#xff1f;文件保存數據存在以下缺點&#xff1a; 文件的安全性問題。文件不利于數據查詢和管理。文件不利于存儲海量數據。…

go語言學習 第5章:函數

第5章&#xff1a;函數 函數是編程中不可或缺的一部分&#xff0c;它封裝了一段可重復使用的代碼&#xff0c;用于執行特定的任務。在Go語言中&#xff0c;函數同樣扮演著重要的角色。本章將詳細介紹Go語言中函數的定義、調用、參數傳遞、返回值處理以及一些高級特性&#xff…

MapReduce 分布式計算模型

what&#xff1a;分解大數據集&#xff0c;并行處理&#xff0c;匯總結果&#xff08;分解組合思想&#xff09; 目的&#xff1a;SQL查詢轉換為MR&#xff0c;理解MR更好優化SQL 優點&#xff1a; 只需關注業務邏輯&#xff08;自定義函數map&#xff0c;reduce&#xff09…

RDMA簡介3之四種子協議對比

RDMA協議共有四種子協議&#xff0c;分別為InfiniBand、iWARP、RoCE v1和RoCE v2協議。這四種協議使用統一的RDMA API&#xff0c;但在具體的網絡層級實現上有所不同&#xff0c;如圖1所示&#xff0c;接下來將分別介紹這四種子協議。 圖1 RDMA四種子協議網絡層級關系圖 Infin…

LabelImg: 開源圖像標注工具指南

LabelImg: 開源圖像標注工具指南 1. 簡介 LabelImg 是一個圖形化的圖像標注工具&#xff0c;使用 Python 和 Qt 開發。它是目標檢測任務中最常用的標注工具之一&#xff0c;支持 PASCAL VOC 和 YOLO 格式的標注輸出。該工具開源、免費&#xff0c;并且跨平臺支持 Windows、Lin…

系統架構設計論文

disstertation 軟考高級-系統架構設計師-論文&#xff1a;論文范圍&#xff08;十大知識領域&#xff09;、歷年論題、預測論題及論述過程、論文要點、論文模板等。 —— 2025 年 4 月 4 日 甲辰年三月初七 清明 目錄 disstertation1、論文范圍&#xff08;十大核心領域&#x…

數學復習筆記 26

5.25&#xff1a;這題還是有點難度的。主要是出現了新的知識點&#xff0c;我現在還沒有那么熟悉這個新的知識點。這塊就是&#xff0c;假設一個矩陣可以寫成一個列向量乘以一個行向量的形式&#xff0c;這兩個向量都是非零向量&#xff0c;那么這個矩陣的秩等于一。這個的原理…

[Java 基礎]注釋

注釋在編程中扮演著非常重要的角色&#xff0c;它們是寫給人類閱讀的&#xff0c;而不是給計算機執行的。良好的注釋可以極大地提高代碼的可讀性和可維護性。 為什么需要注釋&#xff1f; 提高可讀性&#xff1a; 注釋可以解釋代碼的功能、實現思路、特殊處理等&#xff0c;幫…