Skip to content

科学上分之旅

约 769 个字 39 行代码 预计阅读时间 3 分钟

  1. 打开 https://zerotrac.github.io/leetcode_problem_rating/ ,表中的最后一列表示题目的难度,越高题目越难。
  2. 往后翻,做难度分与自己竞赛分接近的题目。
  3. 会做/不会做,就找难度分更高/更低的题目(比如会做难度分就 +25,不会做难度分就 −25)。
  4. 不断练习难度和自己实力相匹配的题目,保证自己处在一个合适的「心流通道」中。

image-20240602192413807

5.30

区间相交

题目

You are given \(N\) intervals of real numbers. The \(i\)-th \((1 \leq i \leq N)\) interval is \([l_i, r_i]\). Find the number of pairs \((i, j)\,(1 \leq i < j \leq N)\) such that the \(i\)-th and \(j\)-th intervals intersect.

求区间相交的个数。

思路

对于区间 [l,r] ,有多少个区间在他之前 \(( l' \le l)\) 并且与他相交

image-20240530225545639

代码链接:AtCoder Beginner Contest 355d

另一种思路:

考虑有多少个区间不相交

问题转化为:对于每个 \(l\) ,有多少个 \(r'\) 满足 r' < l

  • \(l\) 和 r 分别排序,依次扫描每个 \(l\)​ ,同时看看有多少个 r 满足 r < l 。核心代码如下

  • c++ long long res = n*(n-1)/2; j = 0; for(int i = 0; i < n; i ++) { while(j < n && r[j] < l[i]) j += 1; res -= j; }

5.31

滑动窗口

题目

3. 无重复字符的最长子串

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。

思路

滑动窗口:用哈希表来维护从 l 到 r 的字符。

int lengthOfLongestSubstring(string s) {
    int n = s.size(), l = 0, res = 0;
    set<char> st;
    for(int r = 0; r < n; r ++) {
        while(st.count(s[r])) {
            st.erase(s[l ++]);
        }
        st.insert(s[r]);
        res = max(res,r - l + 1);
    }
    return res;
}

MST

题目

You are given a weighted undirected connected graph \(G\) with \(N\) vertices and \(N-1\) edges, where vertices are numbered \(1\) to \(N\) and edges are numbered \(1\) to \(N-1\). Edge \(i\) connects vertices \(a_i\) and \(b_i\) with a weight of \(c_i\). You are given \(Q\) queries to process sequentially. The \(i\)-th query is described as follows:

  • You are given integers \(u_i, v_i, w_i\). Add an edge with weight \(w_i\) between vertices \(u_i\) and \(v_i\) in \(G\). Then, print the sum of the weights of the edges in a minimum spanning tree of \(G\).

对MST q 次加边,求MST的代价。

边权的范围:\(1 \leq c_i, w_i \leq 10\)

思路

实时维护最小生成树中有多少条 1-边 ,2-边 …… 10-边( “X-边“ 代表边权为 X 的边)

  • 使用一个「批量版」的 Kruskal 算法
  • 分别维护加入了所有 1-边,2-边 …… 10-边后的并查集
  • 所以代价为:1*1-边数量 + 2*2-边数量 + …… + 10*10-边数量

怎么知道 MST 中有多少条 X-边呢?

  • 加入 X-边 之前的并查集中连通块的数量 \(-\) 加入 X-边 之后连通块的数量

代码链接:AtCoder Beginner Contest 355f

6.3

状态压缩

Submission #54211161 - AtCoder Beginner Contest 356

6.9

模拟

给你两个 正整数 nk。有 n 个编号从 0n - 1 的孩子按顺序从左到右站成一队。

最初,编号为 0 的孩子拿着一个球,并且向右传球。每过一秒,拿着球的孩子就会将球传给他旁边的孩子。一旦球到达队列的 任一端 ,即编号为 0 的孩子或编号为 n - 1 的孩子处,传球方向就会 反转

返回 k 秒后接到球的孩子的编号。

思路

首先判断k秒后传递的方向,n个数传递n-1秒到达最后一个位置,所有当k/(n-1)是奇数时表示当前传递方向反向,为偶数表示正向;再进行取余运算即可计算出当前所在的位置。

代码

暴力模拟

class Solution {
public:
    int numberOfChild(int n, int k) {
        int res = 0, d = 1;
        for(int i = 0; i < k; i ++) {
            res += d;
            if(res == n - 1 or res == 0) d = - d;
        }
        return res;
    }
};

数学算法 \(O(1)\)

class Solution {
public:
    int numberOfChild(int n, int k) {
        n --;
        int r = k / n;
        if(r & 1) return n - k % n;
        return k % n;
    }
};

Last update: June 9, 2024
Created: June 3, 2024