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 335

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

    2024年01月19日
    浏览(19)
  • AtCoder Beginner Contest 326

    100楼层,一次可以上最多两层,或下最多三层。 给定两楼层,问能否一次到达。 比较大小,然后判断其差是是不是在 (2) 或 (3) 内即可。 神奇的代码 给定一个 (n) ,问不小于 (n) 的形如 (326) 的数字是多少。 形如 (326) 的数字,即数位有 (3) ,且百位 (times) 十位

    2024年02月08日
    浏览(18)
  • AtCoder Beginner Contest 342

    给定一个字符串,两个字符,其中一个只出现一次,找出它的下标。 看第一个字符出现次数,如果是 (1) 则就是它,否则就是 不是它的字符 。 神奇的代码 一排人。 (m) 个询问,每个询问问两个人,谁在左边。 记录一下每个人的下标,然后对于每个询问比较下标大小即可

    2024年03月09日
    浏览(29)
  • AtCoder Beginner Contest 302

    给定怪物的血量 (a) 和你每次攻击扣除的血量 (b) ,问打多少次怪物才会死。 答案即为 (lceil frac{a}{b} rceil = lfloor frac{a + b - 1}{b} rfloor) 神奇的代码 给定一个二维网格,格子上有字母,找到一连串位置,使得其字符串为 (snuke) ,要求这一连串位置俩俩相邻,即有共边或

    2024年02月05日
    浏览(19)
  • AtCoder Beginner Contest 329

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

    2024年02月05日
    浏览(26)
  • AtCoder Beginner Contest 336

    给定一个数 (n) ,将 long 中的 o 重复 (n) 次后输出。 模拟即可。 神奇的代码 给定一个数 (n) ,问 (n) 的二进制表示下的末尾零的数量。 即找到最小的 (i) 使得 (n (1 i)) 不为零的位置。枚举即可。 或者直接用内置函数 __builtin_ctz 。(count tail zero? 神奇的代码 定义一个数

    2024年01月20日
    浏览(25)
  • AtCoder Beginner Contest 328

    给定 (n) 个数字和一个数 (x) 。 问不大于 (x) 的数的和。 按找要求累计符合条件的数的和即可。 神奇的代码 给定一年的月数和一个月的天数。 问有多少对 ((i,j)) ,表示第 (i) 个月的第 (j) 日, (i,j) 的数位上每个数字都是一样的。 范围只有 (O(100^2)) ,枚举所有的

    2024年02月05日
    浏览(23)
  • AtCoder Beginner Contest 344

    给定一个字符串,包含两个 | ,将 | 和两个 | 之间的字符消去。 按照题意模拟即可。 Python 比较简洁。 神奇的代码 给定 (n) 个数,倒序输出。 储存这 (n) 个数,然后倒着输出即可。 神奇的代码 给定三个数组 (a,b,c) ,回答 (q) 次询问。 每次询问,给定 (x) ,问能否从三

    2024年03月10日
    浏览(22)
  • AtCoder Beginner Contest 313

    貌似这次很难,还好去吃烧烤了 发现原来G就是个类欧几里德算法,参考abc283 ex,更了个G 给定 (n) 个数 (a_i) ,问第一个数要成为唯一的最大的数,应该加多少。 找到后面的最大的数 (m) ,答案就是 (max(0, m + 1 - a_0)) 。 神奇的代码 给定 (m) 条关于 (n) 个数的大小关系,

    2024年02月14日
    浏览(20)
  • AtCoder Beginner Contest 337

    给定 (n) 场比赛高桥和青木的得分。 问最后是总分,是高桥高还是青木高,还是打平了。 累计比较大小即可。 神奇的代码 给定一个字符串,问是否形如 AAAA..BBBB...CCCC 。 如果形如上述,那么通过 unique 函数去重后就是有序的,因此去重排序比较即可。 当然也可以朴素找出

    2024年01月21日
    浏览(12)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包