7.13 note

发布于:2025-07-14 ⋅ 阅读:(15) ⋅ 点赞:(0)

lc749.dfs+simulate

通过设计数组记录,来进行大模拟

 

 

lc1806

模拟

math angel:可以用欧拉函数和费马小定理

 class Solution {

public:
    int reinitializePermutation(int n) {
        vector<int> perm(n);
        iota(perm.begin(), perm.end(), 0);
        int operations = 0;
        bool flag = false;


        while (!flag) {
            operations++;
            vector<int> arr(n);
            for (int i = 0; i < n; i++) {
                if (i % 2 == 0) {
                    arr[i] = perm[i / 2];
                } else {
                    arr[i] = perm[n / 2 + (i - 1) / 2];
                }
            }
            perm = arr;
            flag = isInitial(perm);
        }
        return operations;
    }

    bool isInitial(vector<int> perm) {
        int n = perm.size();
        for (int i = 0; i < n; i++) {
            if (perm[i] != i) {
                return false;

            }
        }
        return true;
    }
};
 

lc787.

图论的记忆化搜索

class Solution {
private:
    unordered_map<int, vector<pair<int, int>>> e;
    int memo[101][101]; // 假设n和k不超过100
    int dst;
    int k_max;
    const int INF = INT_MAX / 2; // 避免溢出

    int dfs(int u, int cnt) {
        if (cnt > k_max + 1) {
            return INF;
        }
        if (u == dst) {
            return 0;
        }
        if (memo[u][cnt] != -1) {
            return memo[u][cnt];
        }
        int ans = INF;
        for (auto &edge : e[u]) {
            int v = edge.first;
            int w = edge.second;
            ans = min(ans, dfs(v, cnt + 1) + w);
        }
        memo[u][cnt] = ans;
        return ans;
    }

public:
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int k) {
        // 构建邻接表
        for (auto &f : flights) {
            int from = f[0];
            int to = f[1];
            int weight = f[2];
            e[from].emplace_back(to, weight);
        }
        // 初始化记忆化数组
        memset(memo, -1, sizeof(memo));
        this->dst = dst;
        this->k_max = k;
        // 计算结果
        int ans = dfs(src, 0);
        return ans < INF ? ans : -1;
    }
};
 

lc2101

引爆:建有向图+bfs

找出一系列炸弹中,引爆其中某一颗时能连锁引爆的最大数量。
 
步骤:
 
1. 建关系网:先判断每两颗炸弹之间的距离,如果距离小于其中A炸弹的半径,就记为“A能引爆B”,用一个网络(图)记录这种关系。有向图

 

2. 逐个试爆:对每一颗炸弹,模拟引爆它,然后用“广度优先搜索”(类似一层层扩散)统计能连锁引爆多少颗。


3. 找最大值:记录所有试爆中能引爆的最大数量,就是结果。
 
简单说就是:先搞清楚“谁能引爆谁”,再挨个试,看哪颗能炸得最多。

class Solution {

public:

    int maximumDetonation(vector<vector<int>>& bombs) {

        int n = bombs.size();

        vector<int> g[n];

        for (int i = 0; i < n - 1; ++i) {

            for (int j = i + 1; j < n; ++j) {

                auto& p1 = bombs[i];

                auto& p2 = bombs[j];

                auto dist = hypot(p1[0] - p2[0], p1[1] - p2[1]);

                if (dist <= p1[2]) {

                    g[i].push_back(j);

                }

                if (dist <= p2[2]) {

                    g[j].push_back(i);

                }

            }

        }

        int ans = 0;

        bool vis[n];

        for (int k = 0; k < n; ++k) {

            memset(vis, false, sizeof(vis));

            queue<int> q;

            q.push(k);

            vis[k] = true;

            int cnt = 0;

            while (!q.empty()) {

                int i = q.front();

                q.pop();

                ++cnt;

                for (int j : g[i]) {

                    if (!vis[j]) {

                        vis[j] = true;

                        q.push(j);

                    }

                }

            }

            if (cnt == n) {

                return n;

            }

            ans = max(ans, cnt);

        }

        return ans;

    }

};

 


网站公告

今日签到

点亮在社区的每一天
去签到