zoukankan      html  css  js  c++  java
  • 2021CCPC

    2021CCPC - 桂林

    大晚上看完EDG比赛就立马睡了,醒来状态还行,煎饼果子也不错,豆奶很好喝。()

    A - A Hero Named Magnus

    明天是周一,你很难受

    因为熬夜看比赛

    中国队输了

    你还得上班

    而猛犸他很开心

    因为猛犸他不上ban

    就,(2 imes x-1),签完了。(此时我甚至刚敲完文件头)

    I - PTSD

    就很神奇的是我还没读懂题目意思竹鱼大人直接拿了机子敲了就a了我都没法怎么说这道题因为到现在我还没读完这道题哈哈哈哈。

    D - Assumption is All You Need

    首先是我们推了个结论,一定从最大的数字开始调位置,每次找到调整区间内最大的值,然后与它进行交换,重复操作直至归位或无法操作。因为这样操作可以让大的数字尽可能在前面获得更多交换的可能。这种情况下,最坏情况(降序变成升序)交换次数恰为(n(n-1)/2),当时就直接冲了。

    然后队友写了一发,大致就是记录数字位置,按照数字从大到小遍历数字位置来确认交换顺序,改了两次提了两发wa。当时也看不出能改什么地方了,我就想把机子抢过来边叉边重开。用了类似单调队(虽然但是,真的不需要啥单调队列,我只是最近学dp优化看了单调队列觉得像就写了)来找到交换序列,然后模拟交换并记录位置,前前后后乱七八糟的输出整个人都很乱。(当时手里还捏着道G没有解,因为对于现有算法没法叉掉,并且没有更好的新算法来解决)改完之后真的抱着搏命心态交了,真的过了。就心情挺复杂的。

    #include <bits/stdc++.h>
    #define ll long long
    #define fast ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
    #define pb push_back
    #define ppb pop_back
    using namespace std;
    const int maxn = 2100;
    int m[2100];
    int A[maxn];
    int B[maxn];
    int f1[maxn];
    int f2[maxn];
    vector<pair<int, int>> ans;
    int main()
    {
        fast;
        int T;
        cin >> T;
        while (T--)
        {
            ans.clear();
            int n;
            cin >> n;
            for (int i = 1; i <= n; i++)
            {
                cin >> A[i];
                f1[A[i]] = i;
            }
            for (int i = 1; i <= n; i++)
            {
                cin >> B[i];
                f2[B[i]] = i;
            }
            int flag = 1;
            for (int i = n; i > 1; i--)
            {
                int L = f1[i], R = f2[i];
                if (L > R)
                {
                    flag = 0;
                    break;
                }
                if (L == R)
                {
                    continue;
                }
                int l = 1, r = 0;
                for (int j = L + 1; j <= R; j++)
                {
                    if (A[j] > i)
                        continue;
                    while (l <= r && A[j] > m[r])
                        r--;
                    m[++r] = A[j];
                }
                if (l > r)
                {
                    flag = 0;
                    break;
                }
                while (L < R)
                {
                    ans.pb(make_pair(L, f1[m[l]]));
                    // cout<<L<<' '<<f1[m[l]]<<'
    ';
                    swap(A[L], A[f1[m[l]]]);
                    swap(f1[i], f1[m[l]]);
                    L = f1[i];
                    l++;
                    // for (int j = 1; j <= n; j++)
                    // {
                    //     cout << A[j] << ' ';
                    // }
                    // cout << '
    ';
                    // for (int j = 1; j <= n; j++)
                    // {
                    //     cout << f1[j] << ' ';
                    // }
                    // cout << '
    ';
                    // for (int j = l; j <= r; j++)
                    // {
                    //     cout << m[j] << ' ';
                    // }
                    // cout << '
    ';
                }
                if (flag == 0)
                    break;
            }
            if (flag)
            {
                cout << ans.size() << '
    ';
                for (int i = 0; i < ans.size(); i++)
                {
                    cout << ans[i].first << ' ' << ans[i].second << '
    ';
                }
            }
            else
                cout << "-1
    ";
        }
    }
    

    G - Occupy the Cities

    到死都没能想到很好的方法,看了题解是动态规划就像头被雷劈了。(学了这么久dp看不出这是个dp,说正常也正常,不正常也不正常)

    赛时想的都是什么牛鬼蛇神。

    什么(010)如果第一个(1)向左可以等价为(01100)然后七搞八搞搞不清楚最后写也写不完。

    E - Buy and Delete

    对于一个有向无环图,(Bob)可以一轮删完。对于一个有环图,无论如何(Bob)都可以两步删完(一步拆环一步拆剩余)。最终答案必定在(0,1,2)之中。

    1. 如果没有办法购买任意一条边,答案为(0)
    2. 如果能够购买一个有向环,答案为(2)
    3. 否则,答案为(1)

    对于1,判一轮就行;对于2和3,只需要找到最小有向环权值是否小于题目中给出的(c)

    所以只需要找最小有向环即可。

    然后,只会(dfs),T了,直接判了死刑。

    (n)个点都进行(dij),枚举点对求连通性和最小值。

    补了一发,不知道能不能过,等上gym了再说。

    #include <bits/stdc++.h>
    #define pb push_back
    #define ll long long
    #define fast ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
    using namespace std;
    const int INF = 0x3f3f3f3f;
    const int maxn = 2e3 + 10; // 这里做了修改,当时没注意范围
    struct qnode
    {
        int v;
        int c;
        qnode(int _v = 0, int _c = 0) : v(_v), c(_c) {}
        bool operator<(const qnode &r) const
        {
            return c > r.c;
        }
    };
    struct Edge
    {
        int v;
        int cost;
        Edge(int _v = 0, int _cost = 0) : v(_v), cost(_cost) {}
    };
    vector<Edge> E[maxn];
    bool vis[maxn];
    int dis[maxn][maxn];
    void dijkstra(int n, int start)
    {
        memset(vis, 0, sizeof(vis));
        for (int i = 1; i <= n; i++)
        {
            dis[start][i] = INF;
        }
        priority_queue<qnode> q;
        while (!q.empty())
            q.pop();
        dis[start][start] = 0;
        q.push(qnode(start, 0));
        qnode tmp;
        while (!q.empty())
        {
            tmp = q.top();
            q.pop();
            int u = tmp.v;
            if (vis[u])
                continue;
            vis[u] = 1;
            for (int i = 0; i < E[u].size(); i++)
            {
                int v = E[tmp.v][i].v;
                int cost = E[tmp.v][i].cost;
                if (!vis[v] && dis[start][v] > dis[start][u] + cost)
                {
                    dis[start][v] = dis[start][u] + cost;
                    q.push(qnode(v, dis[start][v]));
                }
            }
        }
    }
    void addedge(int u, int v, int w)
    {
        E[u].pb(Edge(v, w));
    }
    int main()
    {
        fast;
        int n, m, c;
        int u, v, w;
        cin >> n >> m >> c;
        int flag = 0;
        for (int i = 1; i <= m; i++)
        {
            cin >> u >> v >> w;
            if (w <= c)
                flag = 1;
            addedge(u, v, w);
        }
        if (!flag)
        {
            cout << "0
    ";
            return 0;
        }
        for (int i = 1; i <= n; i++)
        {
            dijkstra(n, i);
        }
        int ans = INF;
        for (int i = 1; i <= n; i++)
        {
            for (int j = i + 1; j <= n; j++)
            {
                if (dis[i][j] != INF && dis[j][i] != INF)
                {
                    ans = min(dis[i][j] + dis[j][i], ans);
                }
            }
        }
        if (ans <= c)
            cout << "2
    ";
        else
            cout << "1
    ";
    }
    

    铁牌,CCPC的第一块铁牌,大概率也是最后一块,下周ICPC济南700+冲210,只能说自求多福了。

    大不了再打一年.jpg

  • 相关阅读:
    [LUOGU] P3275 [SCOI2011]糖果
    [BZOJ] 2287: 【POJ Challenge】消失之物
    [BZOJ] 2131: 免费的馅饼
    [JZOJ] 5835. Prime
    [JZOJ] 5837.Omeed
    UF_CAMGEOM_ask_custom_points 封装缺陷
    NX Open 切削层加载
    NX Open 图层说
    c++ Dll调用
    VC操作Excel文件编程相关内容总结
  • 原文地址:https://www.cnblogs.com/endlesskkk/p/15521742.html
Copyright © 2011-2022 走看看