首页 > 其他分享 >2024牛客暑期多校训练营2

2024牛客暑期多校训练营2

时间:2024-07-22 21:30:05浏览次数:7  
标签:int ++ 多校 long cin 2024 牛客 using dp

2024牛客暑期多校训练营2

E-GCD VS XOR_2024牛客暑期多校训练营2 (nowcoder.com)

题意

给定 x,构造 y < x 使得 gcd(x, y) = x ⊕ y

思路

取 x − lowbit(x) 即可,如果 x 是 2 的整数次幂则无解。

代码

#include<bits/stdc++.h>

using namespace std;

using i64 = long long;

void solve() {

    i64 n;
    cin >> n;

    i64 ans = n - (n & -n);
    cout << (ans ? ans : -1) << '\n';

}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int t;
    cin >> t;
    while (t--)
        solve();

    return 0;
}

C-Red Walking on Grid_2024牛客暑期多校训练营2 (nowcoder.com)

题意

给定一个 2 行 n 列的地图,有一些格子为障碍
任选起点,每个格子最多只能走一次(不能走到障碍),求最长路径

思路

考虑 dp,从左往右遍历,遇到上下都是 \(R\) 的时候说明上下可转移,在上面的由下和左转移,在下面的由上和左转移,然后更新答案。

代码

#include<bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;

    string s[2];
    cin >> s[0] >> s[1];

    array<int, 2> dp{0, 0};

    int ans = 0;
    for (int i = 0; i < n; i ++) {
        if (s[0][i] == 'R')
            dp[0] ++;
        else
            dp[0] = 0;
        if (s[1][i] == 'R')
            dp[1] ++;
        else
            dp[1] = 0;
        if (s[0][i] == 'R' && s[1][i] == 'R') {
            dp = {max(dp[0], dp[1] + 1), max({dp[1], dp[0] + 1})};
        }
        ans = max({ans, dp[0], dp[1]});
    }

    ans = max(ans - 1, 0);
    
    cout << ans << '\n';

    return 0;
}

H-Instructions Substring_2024牛客暑期多校训练营2 (nowcoder.com)

题意

平面直角坐标系中,小红初始站在原点
给定一个包含“上、下、左、右”的、长度为 n的指令序列,以及一个
特殊点 (x, y)
求选定一个子串,小红根据该子串序列移动,可以经过特殊点的方案数

思路

考虑前缀和记录每次到达的坐标,枚举左端点,对于从该左端点为起点第一次经过 (x,y) 的右端点,其右端点右边的点均为合法的点。

倒着枚举,找差分下标即可。

代码

#include<bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, x, y;
    cin >> n >> x >> y;

    string s;
    cin >> s;

    vector<array<int, 2>> a(n + 1);
    a[0] = {0, 0};

    for (int i = 0; i < n; i ++) {
        a[i + 1] = a[i];
        if (s[i] == 'W') {
            a[i + 1][1] ++;
        } else if (s[i] == 'S') {
            a[i + 1][1] --;
        } else if (s[i] == 'A') {
            a[i + 1][0]--;
        } else
            a[i + 1][0]++;
    }

    int ans = 0;
    map<array<int, 2>, int> idx;
    for (int i = n; i >= 0; i --) {
        idx[a[i]] = i;
        if (idx.count({a[i][0] + x, a[i][1] + y})) {
            int j = idx[ {a[i][0] + x, a[i][1] + y}];
            j = max(j, i + 1);
            ans += n - j + 1;
        }
    }

    cout << ans << '\n';

    return 0;
}

B-MST_2024牛客暑期多校训练营2 (nowcoder.com)

题意

给定一个 n 个点的简单带权无向图 G
每次询问一个点集 S,求 S 关于 G 导出子图的最小生成树
没有输出 −1

思路

考虑根号分治。

因为没有办法使用邻接矩阵,所有首先用 map,将整个图存下来
考虑两种可能的暴力

设以 \(\sqrt n\) 为界。

对于 \(k\le \sqrt n\):对于给定点集 S,双重循环枚举 S 中的每个点,把其中需要的
边均取出来,并排序,使用 kruskal 算法,求出最小生成树。

对于 \(k>\sqrt n\) :对于给定点集 S,循环枚举 S 中的每个点,在循环枚举该点的
所有边,将需要的边取出来,并排序,使用 kruskal 算法,求出最小生成树。

因为边是双向边,边数组的大小得开 2 倍。

代码

#include<bits/stdc++.h>

using namespace std;

using i64 = long long;

const int N = 1e5 + 10;
map<int, int> g[N];
vector<int> vis(N), node(N), fa(N);
vector<array<int, 3>> edge(N << 1);

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m, q;
    cin >> n >> m >> q;

    for (int i = 0; i < m; i ++) {
        int u, v, w;
        cin >> u >> v >> w;
        g[u][v] = g[v][u] = w;
    }

    const int base = sqrt(n);

    auto find = [&](auto & self, int x)->int{
        return fa[x] == x ? x : fa[x] = self(self, fa[x]);
    };

    while (q--) {
        int k;
        cin >> k;

        for (int i = 0; i < k; i ++) {
            cin >> node[i];
            int u = node[i];
            fa[u] = u;
            vis[u] = 1;
        }

        int cnt = 0;
        if (k <= base) {
            for (int i = 0; i < k; i ++)
                for (int j = i + 1; j < k; j ++)
                    if (g[node[i]].count(node[j]))
                        edge[cnt++] = { g[node[i]][node[j]], node[i], node[j]};
        } else {
            for (int i = 0; i < k; i ++) {
                int u = node[i];
                for (auto &[v, w] : g[u])
                    if (vis[v])
                        edge[cnt++] = {w, u, v};
            }
        }

        sort(edge.begin(), edge.begin() + cnt);

        i64 ans = 0, kuai = 0;
        for (int i = 0; i < cnt; i ++) {
            auto &[w, u, v] = edge[i];
            u = find(find, u), v = find(find, v);
            if (u != v) {
                fa[u] = v;
                ans += w;
                kuai ++;
            }
            if (kuai == k - 1) break;
        }

        for (int i = 0; i < k; i ++) {
            int u = node[i];
            fa[u] = u;
            vis[u] = 0;
        }

        if (kuai != k - 1) ans = -1;

        cout << ans << '\n';

    }

    return 0;
}

I-Red Playing Cards_2024牛客暑期多校训练营2 (nowcoder.com)

题意

给定一个长度为 2 × n 的数组,1 到 n 每个元素恰好出现两次
每次操作可以删除一个长度不小于 2 的连续子数组,需要满足该子数组
首尾相同,获得该连续子数组“首尾元素值”乘以“元素数量”的分数
问最终可以得到的最大分数

思路

处理出 \(1\sim n\) 每个数包含的区间,考虑从大到小去枚举每个区间产生的贡献,因为大数产生的贡献一定比小数产生的更多。

设 \(f_x\) 表示 x 这个数所包含的区间所产生的贡献。

遍历 x 所包含的区间,设 \(dp_i\) 表示当前 \(l_x+1\sim i\) 所产生的贡献,如果对于 \(a_i\) 这个数,其 \([l_{a_i},r_{a_i}] \subset [l_x,r_x]\) ,那么有 \(dp_{r_{a_i}+1} = \max(dp_{r_{a_i}+1},dp_i+f_{a_i})\),对于其他位置, x 产生的贡献就是 x,即 \(dp_{i+1}=\max(dp_i+x,dp_{i+1})\),开始在两端补 0 的话,最后的答案即就是 \(f_0\)。

代码

#include<bits/stdc++.h>

using namespace std;

using i64 = long long;

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;
    n ++;

    vector<int> a(2 * n);
    for (int i = 1; i < 2 * n - 1; i ++)
        cin >> a[i];

    vector<int> l(n, -1), r(n);
    for (int i = 0; i < 2 * n; i ++) {
        cin >> a[i];
        if (l[a[i]] == -1) {
            l[a[i]] = i;
        } else {
            r[a[i]] = i;
        }
    }

    vector<int> f(n);
    for (int x = n - 1; x >= 0; x --) {
        vector<int> dp(2 * n + 1);
        for (int i = l[x] + 1; i < r[x]; i ++) {
            if (dp[i + 1] < dp[i] + x)
                dp[i + 1] = dp[i] + x;
            if (i == l[a[i]] && r[a[i]] < r[x]) {
                if (dp[r[a[i]] + 1] < dp[i] + f[a[i]])
                    dp[r[a[i]] + 1] = dp[i] + f[a[i]];
            }
        }
        f[x] = 2 * x + dp[r[x]];
    }

    cout << f[0] << '\n';

    return 0;
}

G-The Set of Squares_2024牛客暑期多校训练营2 (nowcoder.com)

题意

思路

代码


标签:int,++,多校,long,cin,2024,牛客,using,dp
From: https://www.cnblogs.com/Kescholar/p/18316958

相关文章

  • 闲话:IMO 2024 P5
    这道题其实挺搞心态的,至少看到\(2024\)这种具体的数字一般都会想到\(12,13\)之类的东西上去吧?当然这几天知乎看饱了都知道答案是\(3\)了。下面给一下我的构造:第一步从\((1,1)\)走到\((2,1)\),然后一路往右插过去,问出第二行的鬼的位置,位于\((2,x)\)。如果这个鬼不在......
  • SMU Summer 2024 Contest Round 6
    AManyFormulas思路:二进制枚举voidsolve(){strings;cin>>s;intn=s.size();intm=pow(2,n-1);intans=0;for(inti=0;i<m;++i){intnow=0,sum=0;for(intj=0;j<n;++j){......
  • 2024 Selenium10个替代品
     随着自动化测试需求的不断增长,Selenium作为广泛使用的自动化测试工具,虽然功能强大,但也存在一些限制和挑战。在2024年,越来越多的替代工具涌现,它们提供了更高效、更易用的解决方案。那么,哪些替代品值得我们关注呢?  在自动化测试领域,除了Selenium,还有哪些工具能够满足我们的......
  • 2024信友队蓝润暑期集训提高1班②Day7
    知识总结Tarjan算法Tarjan算法是一种用于计算有向图中强连通分量的算法。Tarjan算法的基本思想是:首先,将图中每个节点标记为未访问。然后,从某个节点开始,对该节点进行DFS,并记录该节点的入度(即该节点的邻居个数)。对于每个节点,如果其入度为0,则说明它是一个根节点,将它标记......
  • Camtasia2024苹果mac+win电脑破解版安装包下载!附带激活码许可证号
    在视频创作和教学内容制作领域,CamtasiaStudio一直是备受青睐的工具。随着2024版本的推出,CamtasiaStudio带来了更多强大的功能和优化,为用户提供了更高效、更便捷的创作体验。接下来,让我们详细了解一下CamtasiaStudio2024的新功能,并深入学习它的使用教程。camtasia202......
  • 2024钉钉杯及2023钉钉杯ABC题分析
    钉钉杯,通常指的是钉钉杯大数据挑战赛,这是一场由阿里巴巴旗下钉钉举办的全国性大数据竞赛。以下是对钉钉杯的详细解析:一、竞赛背景与目的钉钉杯大数据挑战赛旨在通过大数据竞赛的形式,激发学生对大数据技术的兴趣,提升他们的数据分析和数据挖掘能力。同时,该竞赛也为学生提供了一......
  • 【ACM出版】2024年云计算与大数据国际学术会议(ICCBD 2024,7月26-28)
    2024年云计算与大数据国际学术会议(ICCBD2024)将于2024年7月26-28日在中国大理召开。ICCBD2024将围绕“云计算与大数据”的最新研究领域,旨在为从事研究的专家、学者、工程师和技术人员提供一个国际平台,分享科研成果和尖端技术,了解学术发展趋势,拓宽研究思路,加强学术研......
  • 2024/7/22 模拟赛记录
    这次的模拟赛比较简单。150T1:100T2:30T3:0T4:20T1:【题目描述】给定两个字符串a,b,从a中选一段前缀,b中选一段后缀(前后缀都可以为空),并将选出的后缀拼在选出的前缀后面。你需要求出有多少种本质不同的串(可以为空)场上思路:上来直接敲了个扩展kmp,仔细读题后发现这道题和kmp......
  • 牛客周赛52
    ​ 小红的最大字典 ​编辑思路:使用优先队列进行多路归并#include<bits/stdc++.h>#defineintlonglong#definexfirst#defineysecond#defineendl'\n'#definepqpriority_queueusingnamespacestd;typedefpair<int,int>pii;voidsolve(){ priority_q......
  • 2024“钉耙编程”中国大学生算法设计超级联赛(2)
    Preface最唐氏的一集,前中期被A卡得数次破防红温,后期经典不知道在干嘛摆着摆着就结束了可惜的是徐神最后1h写的B因为两个数组搞反了一直没过,赛后看了眼就过了,这下狠狠地掉Rating了鸡爪丁真构造题,但有人连WA三发怎么回事呢首先不难想到最大化和\(1\)连边的数量,首......