AtCoder Beginner Contest 292 (A - E) 记录第一场ABC

这篇具有很好参考价值的文章主要介绍了AtCoder Beginner Contest 292 (A - E) 记录第一场ABC。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

本来晚上在打Acwing周赛,最后一题Trie想不出来咋写,看群里有人说ABC要开始了,想着没打过ABC就去报了一下,感觉难度大概是cf的Div3到Div4之间吧,总共写了五个题,E题想复杂了快结束才交过。总的来说手速很重要。

Q1 A - CAPS LOCK

题意:给一个字符串,要求把小写字母改成大写。
分析: 循环模拟下就可以了,时间复杂度 O ( n ) O(n) O(n)

void solve()
{
    string s;
    cin >> s;
 
    for(auto &c : s)
    {
        if(c >= 'a' && c <= 'z') c += 'A' - 'a';
    }
 
    cout << s << endl;
}

Q2 Yellow and Red Card

题意:有n个人,发生过q个事件,每个事件要么是某人领黄牌/红牌/询问某人是否出局,累计获得两张黄牌或者是得到过红牌就会出局。
分析:开一个数组cnt记录即可,黄牌+1, 红牌+2. 大于等于2的就要出局了。时间复杂度 O ( q ) O(q) O(q)

{
    cin >> n >> q;
    vector<int> cnt(n + 1);
    while(q--)
    {
        int t, x;
        cin >> t >> x;
        if(t == 1) cnt[x] += 1;
        else if(t == 2) cnt[x] += 2;
        else cout << (cnt[x] >= 2 ? "Yes" : "No") << endl;
    }
}

Q3 Four Variables

题意:问四元组(A, B, C, D)满足AB + CD = n 的个数。
分析:先考虑简单的问题,如果问X + Y = n,求(X, Y)的数量,答案显然。然后再考虑怎么凑成X,就是X的因子对的数量,Y也是同理。设 f [ x ] f[x] f[x]表示x的因子对数量,那么答案就是 f [ 1 ] ∗ f [ n − 1 ] + f [ 2 ] ∗ f [ n − 2 ] + . . . + f [ n − 1 ] ∗ f [ 1 ] 。 f[1] * f[n - 1] + f[2] * f[n - 2] + ... + f[n - 1] * f[1]。 f[1]f[n1]+f[2]f[n2]+...+f[n1]f[1] 时间复杂度 O ( n n ) O(n\sqrt{n}) O(nn )

#define int long long
void solve()
{
    cin >> n;
    vector<int> f(n + 1);
    for(int i = 1; i <= n; ++i)
    {
        int t = i;
        for(int j = 1; j <= t / j; ++j)
            if(t % j == 0) f[i] += 1 + (j != t / j);
    }
 
    int ans = 0;
    for(int i = 1; i <= n; ++i)
    {
        int j = n - i;
        ans += f[i] * f[j];
    }
    cout << ans << endl;
}

Q4 D - Unicyclic Components

题意:给一张有向图图,询问是否每个连通分量内点的数量都等于边的数量。
分析:据说分别维护点和边的并查集和集合内元素数量的做法可以过,貌似官方给的题解也是这么做的,但是我写的是维护连通块内环的个数。把题目给出的有向图当作无向图,什么时候连通分量里面的点的数量会等于边的数量呢?设点数为 x x x, 边数为 y y y.如果连通分量内无环,因为各点都连通,所以 y = x − 1 y = x - 1 y=x1。可以发现如果要让 x = = y x == y x==y, 需要在原图上补充一条边,因为原图已经连通,加上的这条边一定会增添一个环。用 c n t cnt cnt维护并查集集合内环数量,合并 a , b a, b a,b的时候,如果 a , b a, b a,b之前不在一个集合内,那么他们环的数量相加(因为此前这两个连通分量并不连通,所以环数量直接相加即可)。如果a, b之前已经在一个集合,那么这个集合的环数量+1. 最后判断每个集合的环数量是否恰好等于1.时间复杂度 O ( n ) O(n) O(n)

/*
 * @Author: gorsonpy
 * @Date: 2023-03-04 20:21:52
 * @LastEditors: gorsonpy
 * @LastEditTime: 2023-03-04 20:26:28
 * @FilePath: \vscode-c\D_-_Unicyclic_Components.cpp
 * @Description: 
 */
#include<iostream>
#include<cstring>
using namespace std;
const int N = 2e5 + 10;

int p[N], cnt[N];
int n, m;

int find(int x)
{
    if(x != p[x]) p[x] = find(p[x]);
    return p[x];
}
int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; ++i) p[i] = i, cnt[i] = 0;
    while(m--)
    {
        int a, b;
        cin >> a >> b;
        int pa = find(a), pb = find(b);
        if(pa != pb) p[pa] = pb, cnt[pb] += cnt[pa];
        else ++cnt[pb];
    }

    bool ok = true;
    for(int i = 1; i <= n; ++i)
        if(p[i] == i)
        {
            if(cnt[i] != 1) ok = false;
        }
    

    cout << (ok ? "Yes" : "No") << endl;
    return 0;
}

Q5 E - Transitivity

写完D看了一下群,有人说E是搜索。。当时就紧张了因为不太会写搜索,导致把题目想歪了。。其实不用搜索也可以做的,比赛后一个小时都在写E,不过F那个几何去想应该也做不出来吧(

题意:给定一张有向图,每次操作可以加一条边,问最少操作次数,使得对于整张图,若存在a到b的边,存在b到c的边,那么一定也有a到c的边。

分析:注意到数据规模并不大,只有2000点,2000边。考虑一下暴力做法。实际上,只需要开数组记录对于每个点, 进入他的点集合in, 和他出去的out。 然后循环所有的点i,看每个(x, y)是否有x到y的边,x是进入i的一个点,y是i出去的一个点。如果没边加上就行了,答案加1, 就这么简单。但是可能会想,为什么做一次就可以了?会不会存在比如说第一次加的边引起后续反应了,导致还要再加一轮边?实际上并不会。因为本题除了暴力还有一个性质:在最终的图中,x所直接连的点一定是在原始的图中x所能抵达的点(不一定是直接相连)。反之亦然。这个用归纳法是显然的,因为每次我们添加边(x, y)的时候并没有改变x ->y的可达性。所以这个做法实际上等价于搜索,也就是找原图中点i所能抵达的点p,然后计算i到p路径上的边数量,最后减去原图已有的边。 时间复杂度 O ( n m ) O(nm) O(nm)文章来源地址https://www.toymoban.com/news/detail-418732.html

#define pb push_back
int g[N][N];
void solve()
{
    cin >> n >> m;
    vector<vector<int>> in(n + 1), out(n + 1);
    while(m--)
    {
        int x, y;
        cin >> x >> y;
        out[x].pb(y);
        in[y].pb(x);
        g[x][y] ++;
    }
    int ans = 0;
    for(int i = 1; i <= n; ++i)
    {
        auto din = in[i], dout = out[i];
        for(auto x : din)
            for(auto y : dout)
            {
                if(x == y) continue;
                if(!g[x][y]) 
                {
                    ++ans;
                    g[x][y] ++;
                    in[y].pb(x);
                    out[x].pb(y);
                }
            }
    }
    cout << ans << endl;
}

到了这里,关于AtCoder Beginner Contest 292 (A - E) 记录第一场ABC的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • AtCoder Beginner Contest 304

    依次给定每个人的姓名和年龄,排成一圈。从年龄最小的人依次输出姓名。 找到年龄最小的,依次输出就好了。 神奇的代码 给定一个数字,如果其超过三位数,则仅保留其最高三位,低位数字全部置为0。 读一个 string ,直接赋值即可。 神奇的代码 给定 (n) 个人的坐标,第

    2024年02月07日
    浏览(39)
  • AtCoder Beginner Contest 329

    劳累一天不该写题,启发式合并都写错了 给定一个字符串,将每个字符输出出来,中间留个空格。 遍历输出即可。 神奇的代码 给定一个数组,找出次大的数。 遍历一下,从非最大的数求一个最大值即可。 神奇的代码 给定一个字符串,问有多少个连续的子串,其由一个字母

    2024年02月05日
    浏览(75)
  • AtCoder Beginner Contest 339

    给一个网址,问它的后缀是多少。 找到最后的\\\'.\\\'的位置,然后输出后面的字符串即可。 python 可以一行。 神奇的代码 二维网格,上下左右相连,左上原点。初始全部为白色,位于原点,面朝上。 进行 (n) 次操作,每次操作,将当前格子颜色黑白反转,然后 如果原来是白色

    2024年02月19日
    浏览(31)
  • AtCoder Beginner Contest 340

    给定等差数列的 首项 、 末项 、 公差 。 输出这个等差数列。 从 首相 依次累加 公差 到 末项 即可。 神奇的代码 依次进行 (Q) 次操作,分两种。 1 x ,将 x 放到数组 (a) 的末尾。 2 k ,输出数组 (a) 的倒数第 (k) 项。 用 vector 模拟即可,操作 2 可快速寻址访问。 神奇的代

    2024年02月19日
    浏览(33)
  • AtCoder Beginner Contest 314

    怎么好多陌生单词 审核怎么这么逆天,半小时还没审完 给定 (pi) 的值以及数 (n) ,要求保留 (n) 位小数输出,不四舍五入。 字符串形式储存然后截取末尾即可。 神奇的代码 (n) 个人玩轮盘赌游戏,简单说就是一个转盘有 (37) 个数字以及一个箭头,箭头会等概率停在某

    2024年02月13日
    浏览(40)
  • AtCoder Beginner Contest 308

    这几天在收拾东西搬家,先附上代码,晚点补上题解 补完了 感觉这次FG都写不太明白 给定八个数,问是否满足以下要求: 不严格升序 每个数在 (100 sim 675) 之间 每个数都是 (25) 的倍数 依次对每个数判断是否符合这三个条件即可。 神奇的代码 高桥吃 (n) 份寿司,寿司分

    2024年02月11日
    浏览(30)
  • AtCoder Beginner Contest 345

    给定一个字符串,问是不是形如 ======...==== 的字符串。 根据长度构造出期望的字符串,再判断是否相等即可。 神奇的代码 给定 (a) ,输出 (lceil frac{a}{10} rceil) 上下取整的转换, (lceil frac{a}{10} rceil = lfloor frac{a + 9}{10} rfloor) 。用下取整即可。 Python 的 // 是下取证,

    2024年03月21日
    浏览(36)
  • AtCoder Beginner Contest 309

    感觉F写了个乱搞做法 给定一个 (3 times 3) 的网格,以及两个数字。 问这两个数字是否 水平相邻 。 求出两个数字的横纵坐标,看是否横坐标相同,纵坐标差一即可。 读题不仔细,开题就WA了。 神奇的代码 给定一个矩形。将最外围的数字顺时针旋转一格。 可以模拟一个指针

    2024年02月13日
    浏览(32)
  • AtCoder Beginner Contest 321

    给定一个数,问从高位到低位,数字是不是递减的。 可以以字符串读入,然后依次判断即可。 神奇的代码 给定 (n-1) 个数字,问最后一个数字最少是多少,使得你的分数不小于 (x) 。 数字在 ([0,100]) 之间。分数是去掉最低最高后的和。 因为范围不大,直接枚举最后一个数

    2024年02月08日
    浏览(31)
  • AtCoder Beginner Contest 335

    给定一个字符串,将最后一位改成 4 。 模拟即可。 神奇的代码 给定 (n) ,按字典序输出非负整数 (i,j,k) ,使得 (i+j+kleq n) (n) 只有 (21) ,直接 (O(n^3)) 枚举判断即可。 神奇的代码 二维网格,贪吃蛇,移动,进行 (q) 次操作,分两种 指定贪吃蛇下一步移动的方向 指定

    2024年01月19日
    浏览(32)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包