1 条题解

  • 0
    @ 2026-5-4 12:25:59

    解题思路

    在这个问题中,你得到了一幅图,每个顶点恰好有一条出边。你需要回答:如果你从某个顶点出发,沿着当前顶点的出边移动,直到某个顶点被第二次访问,那么哪个顶点会最先被访问两次?

    这个问题可以通过直接模拟来解决。你可以选择一个起始顶点(即第一个被老师在徽章上打洞的学生),然后维护当前顶点,以及每个顶点被访问的次数。在移动到下一个顶点后,检查该顶点是否已经被访问过,并更新它的访问标记。

    这种解法的复杂度为 O(n2)O(n^2),实现起来非常简单。虽然可以优化到 O(n)O(n),但本题中并不需要。这是一个容易且有用的练习,留给读者自行完成。


    代码实现

    #include <bits/stdc++.h>
    using namespace std;
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(nullptr);
    
        int n;
        cin >> n;
        vector<int> p(n + 1);
        for (int i = 1; i <= n; ++i) {
            cin >> p[i];
        }
    
        for (int start = 1; start <= n; ++start) {
            vector<int> vis(n + 1, 0);
            int cur = start;
            while (true) {
                if (vis[cur] == 1) {
                    cout << cur << " \n"[start == n];
                    break;
                }
                vis[cur] = 1;
                cur = p[cur];
            }
        }
    
        return 0;
    }
    • 1

    信息

    ID
    6780
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    2
    已通过
    1
    上传者