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

推荐订阅源

Google DeepMind News
Google DeepMind News
B
Blog RSS Feed
The GitHub Blog
The GitHub Blog
Recent Announcements
Recent Announcements
A
About on SuperTechFans
G
Google Developers Blog
aimingoo的专栏
aimingoo的专栏
U
Unit 42
WordPress大学
WordPress大学
Y
Y Combinator Blog
罗磊的独立博客
J
Java Code Geeks
Microsoft Azure Blog
Microsoft Azure Blog
腾讯CDC
博客园 - 叶小钗
Stack Overflow Blog
Stack Overflow Blog
Engineering at Meta
Engineering at Meta
Microsoft Security Blog
Microsoft Security Blog
GbyAI
GbyAI
V
V2EX
雷峰网
雷峰网
H
Hackread – Cybersecurity News, Data Breaches, AI and More
S
SegmentFault 最新的问题
酷 壳 – CoolShell
酷 壳 – CoolShell

ABB00717

SecList Knock Pivoting and Tunneling Broken Authentication File Inclusion Login Brute Forcing Reverse Shell Web Fuzzing HTB - SpeedNet PHP Filter to RCE Redis HTB - Pollution HTB - Pollution 工具 常見服務 HTB - BroScience HTB - BroScience 如何把爛爛的 shell 升級成好用的 TTY 滲透筆記 HTB - Imagery HTB - Imagery HTB - Reset HTB - Reset HTB - Trick HTB - Trick HTB - Editorial HTB - Editorial 150. Evaluate Reverse Polish Notation droopescan 安裝找不到 module imp 解決「桌面背景被當成一個視窗不斷重新彈出並覆蓋其他視窗」的問題
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;
}

今天我學到的新東西