惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Engineering at Meta
Engineering at Meta
P
Privacy International News Feed
W
WeLiveSecurity
Spread Privacy
Spread Privacy
S
Schneier on Security
Google Online Security Blog
Google Online Security Blog
N
News and Events Feed by Topic
Forbes - Security
Forbes - Security
Cisco Talos Blog
Cisco Talos Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
L
Lohrmann on Cybersecurity
P
Privacy & Cybersecurity Law Blog
T
The Exploit Database - CXSecurity.com
C
CXSECURITY Database RSS Feed - CXSecurity.com
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
小众软件
小众软件
人人都是产品经理
人人都是产品经理
SecWiki News
SecWiki News
Schneier on Security
Schneier on Security
月光博客
月光博客
博客园_首页
腾讯CDC
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google DeepMind News
Google DeepMind News
Cyberwarzone
Cyberwarzone
www.infosecurity-magazine.com
www.infosecurity-magazine.com
AWS News Blog
AWS News Blog
WordPress大学
WordPress大学
AI
AI
酷 壳 – CoolShell
酷 壳 – CoolShell
Hacker News: Ask HN
Hacker News: Ask HN
Attack and Defense Labs
Attack and Defense Labs
IT之家
IT之家
P
Proofpoint News Feed
The Hacker News
The Hacker News
The Cloudflare Blog
Vercel News
Vercel News
Application and Cybersecurity Blog
Application and Cybersecurity Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Cloudbric
Cloudbric
C
Cisco Blogs
TaoSecurity Blog
TaoSecurity Blog
I
Intezer
Jina AI
Jina AI
雷峰网
雷峰网
阮一峰的网络日志
阮一峰的网络日志
Microsoft Azure Blog
Microsoft Azure Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
A
About on SuperTechFans
B
Blog

ABB00717

medusa 找不到 ssh module 中文文案排版指北 BugBounty Playbook 小知識 透過 Ubuntu 26 設定 Windows 11 雙系統並使用 Image Recovery 之踩坑全紀錄 清除 git history 中的機敏資料 編譯器筆記 部落格聚集地 HTB - Busqueda 788. Rotated Digits 396. Rotate Function 幫耳機補血! 紀錄/週刊/ 做過的夢(旅行) 做過的夢 週刊 Vol.18 週刊 Vol.17 週刊 Vol.16 做過的夢(火箭推進器和追蹤導彈) 在 Ubuntu 24.04 中安裝 python2 和 pip2 動態牆 紀錄/音樂/ 用 miniflux 和 Cloudflare Tunnel 自架 RSS Reader 週記 Vol.15 關於用了 GCC 擴充功能,而被批評不夠 Clean Code 這檔事 GDB Makefile HTB - TwoMillion 週記 Vol.14 紀錄/Hack-The-Box/ 週記 Vol.13 ABB00717's Blog 1980. Find Unique Binary String 週記 Vol.12 紀錄/Leetcode/ 在互聯網上,什麼該說,什麼又不該說? 週記 Vol.8 週記 Vol.7 週記 Vol.6 天才之於一種義務 就算 LLM 能解答所有問題,你也不該放棄學習 Stack-Based Buffer Overflow 筆記/書籍/ 《絕佳時間》 週記 Vol.5 偽深刻的自我解構 筆記/Linux-雜項筆記/ 解決 Ubuntu 待機後喚醒異常的問題 將應用程式新增到 GNOME 的 Activities Overview 週記 Vol.4 Assembly Language 週記 Vol.3 筆記/ 文章/ 紀錄/ 資源/ 挑戰 週記 Vol.2 部落格該有的東西 週記 Vol.1 數學符號表 Advent of Code Day 8 Obsidian 無痛轉成 Blog Advent of Code Day 6
Advent of Code Day 7
2025-12-07 · via ABB00717

Part 1

遍歷整個 fields,如果上面有 | 就代表光束會射下來,如果這格是 ^ 就會需要分裂光束,也就是讓左右兩格也都變成 |

#include <fstream>
#include <iostream>
#include <string>
#include <vector>
 
int main() {
    std::vector<std::string> fields;
    int result = 0;
 
    // Read inputs into inputFile
    std::ifstream inputFile("input-day7");
    std::string line;
    while (std::getline(inputFile, line)) {
        fields.push_back(line);
    }
 
    for (char &ch : fields[0]) {
        if (ch == 'S') {
            ch = '|';
        }
    }
 
    // for (each row start from row2)
    for (int row = 1; row < fields.size(); row++) {
        for (int col = 0; col < fields[0].size(); col++) {
            // if (up block is '|')
            if (fields[row - 1][col] == '|') {
                if (fields[row][col] != '^') {
                    fields[row][col] = '|';
                } else {
                    // turn the left and right block to '|' if that
                    // block is '.'
                    result++;
                    if (col != 0 && fields[row][col-1] != '^')
                        fields[row][col-1] = '|';
                    if (col != fields[0].size()-1 && fields[row][col+1] != '^')
                        fields[row][col+1] = '|';
                }
            }
        }
    }
 
    std::cout << result << std::endl;
}

Part 2

就是現在這個分裂器(splitter),也就是這個光束產生的「光束宇宙」數量,是左右兩邊光束打下去後的光束宇宙數量加總。

int helper(index, row, fields: (from {i} to end)) {
    if (fields is NULL) {
        return 1;
    }
 
    if (under the index the block is '^')
        // helper to left
        sum += helper(index-1, row + 1, fields(from row+2 to end)) 
        // helper to right
        sum += helper(index+1, row + 1, fields(from row+2 to end)) 
    else
        return helper(index, row + 1, fields(from row+2 to end))
}

但這樣的時間複雜度會達到驚人的 !遞迴的威力,寶貝!因為它就是個完美的二元樹,遇到一個 helper 就會分裂,而假設每層都有一個 helper,那麼根據測資,數量就是

但因為每次同樣 indexrow 的結果都是一樣的,所以可以把結果紀錄起來,也就是可以用動態規劃。

只要能寫成遞迴,而且結果不會根據狀態改變,就可以用動態規劃。

因為相當於每格最多計算一次,所以時間複雜度會變成簡單的

#include <fstream>
#include <iostream>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
#include <span>
 
struct PairHash {
    template <class T1, class T2>
    std::size_t operator()(const std::pair<T1, T2>& p) const {
        auto h1 = std::hash<T1>{}(p.first);
        auto h2 = std::hash<T2>{}(p.second);
        return h1 ^ (h2 << 1); 
    }
};
 
#define DPTYPE std::unordered_map<std::pair<int, int>, long long, PairHash>
 
// int helper(index, row, dp, fields: (from {i} to end))
long long helper(int index, int row, DPTYPE& dp, std::vector<std::string>& fields) {
    if (row == fields.size()-1)
        return 1;
 
    if (dp.count({row, index}))
        return dp[{row, index}];
 
    int curRow = row+1;
    long long result = 0;
    if (fields[curRow][index] == '^') {
        if (index != 0)
            result += helper(index-1, curRow, dp, fields);
        if (index != fields[0].size()-1)
            result += helper(index+1, curRow, dp, fields);
    } else {
        return helper(index, curRow, dp, fields);
    }
 
    return dp[{row, index}] = result;
}
 
int main() {
    std::vector<std::string> fields;
    long long result = 0;
 
    // Read inputs into inputFile
    std::ifstream inputFile("input-day7");
    std::string line;
    while (std::getline(inputFile, line)) {
        fields.push_back(line);
    }
 
    DPTYPE dp;
    for (int i = 0; i < fields[0].size(); i++) {
        if (fields[0][i] == 'S') {
            result = helper(i, 0, dp, fields);
        }
    }
 
    std::cout << result << std::endl;
}

今天我學到的新東西