首页 > 其他分享 >AtCoder Beginner Contest 380 Solution

AtCoder Beginner Contest 380 Solution

时间:2024-11-30 23:45:27浏览次数:9  
标签:AtCoder int Solution cin 380 ++ 字符串 翻转 size

A - 123233

6个数问是不是1个1,2个2,3个3

#include <bits/stdc++.h>
using namespace std;
int a[4];
int main()
{
    string s;
    cin >> s;
    for (int i = 0; i < s.size(); i++)
        a[s[i] - '0']++;
    if (a[1] == 1 && a[2] == 2 && a[3] == 3)
        cout << "Yes";
    else
        cout << "No";
    return 0;
}

B - Hurdle Parsing

统计每两个|之间有多少-。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    string s;
    cin >> s;
    vector<int> a;
    int cnt = 0;
    for (int i = 1;i < s.size();i++) {
        if (s[i] == '|') {
            a.push_back(cnt);
            cnt = 0;
        }
        else
            cnt++;
    }
    for (int i = 0;i < a.size();i++)
        cout << a[i] << " ";
    return 0;
}

C - Move Segment

题意

给定一个01子串。

连续的1视为一个块。

现将第k个块移动到第k−1个块前面。

解法

把每一段的长度以及是0是1存进一个vector里,同时记录第k个块在vector里的下标,然后swap一下他和前一段即可。

#include<bits/stdc++.h>
using namespace std;
int main() {
    int n, k;
    cin >> n >> k;
    string s;
    cin >> s;
    int idx = 0, id;
    vector<pair<int, char> > p;//存长度,是0是1。
    for (int i = 0; i < n; i++) {
        int j = i;
        while (j + 1 < n && s[j + 1] == s[j]) j++;
        if (s[i] == '1') {
            ++idx;
            if (idx == k)//记录第k个全1段在p中的下标
                id = p.size();
        }
        p.push_back({ j - i + 1, s[i] });
        i = j;
    }
    if (id)
        swap(p[id], p[id - 1]);
    for (int i = 0;i < p.size();i++) {
        cout << string(p[i].first, p[i].second);
    }
    return 0;
}

D - Strange Mirroring

题意

给定一个字符串s,重复下述操作无数次:

  • 将s的字母大小写反转成t,加到s后面

给定q个询问,每个询问问第k个字符是什么。

思路

最后整个字符串就是由无数s和s的翻转构成,我们设s的翻转叫做s',那么我们现在考虑第i个段是s还是s‘。

举例现在求第30个字符串是原字符串还是翻转字符串:

一定在某次操作中,将第1-16个字符串翻转并复制到了17-32个字符串,所以可以求出第30个字符串是第14个字符串的翻转。

同理,在某次操作中,将1-8个字符串翻转到了9-16,第14个字符串就是第6个字符串的翻转。

以此类推,我们可以求出第30个字符串是原始字符串的几次翻转,求的次数是log次。

所以写程序就是模仿我们这个过程,每次找出是哪一次操作复制到的我们当前位置的字符串,然后找到对应的位置继续求即可。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll pow2[70];
int main() {
    string s;
    cin >> s;
    pow2[0] = 1;
    for (int i = 1;pow2[i - 1] <= 1e18;i++)
        pow2[i] = pow2[i - 1] * 2;//预处理2的次幂,即每次操作的翻倍点
    int Q;
    cin >> Q;
    while (Q--) {
        ll K;
        cin >> K;
        K--;
        ll k = (K / (int)s.size()) + 1;
        K %= (int)s.size();
        bool flag = 1;
        while (k != 1) {
            int id = lower_bound(pow2, pow2 + 61, k) - pow2-1;//找出当前下标是由哪一段翻倍
            k = k - pow2[id];//还原翻倍点
            flag ^= 1;//取反 表示最后是翻转的还是非翻转
        }
        if (flag) cout << s[K] << " ";
        else {
            if (isupper(s[K]))
                cout << (char)tolower(s[K]) << " ";
            else
                cout << (char)toupper(s[K]) << " ";
        }
    }
    return 0;
}

E - 1D Bucket Tool

题意

从左到右n个格子,第i个格子颜色为i 。

维护q个查询,分两种:

  • 1 x c:将第x个格子连同周围与其同色的格子涂成颜色c
  • 2 c:问颜色c的格子数

解法

用一个set维护每一段相同颜色区间的左端点以及颜色,经过一次修改之后,看新的颜色和前一段或者后一段是否相同,如果是相同颜色那么就可以合并,顺便记录一个数组维护每个颜色的格子数就行。

#include<bits/stdc++.h>
using namespace std;
int cnt[500005];//记录每个颜色的格子数
int main() {
    set<pair<int, int> > s;//左端点,颜色
    int n, Q;
    cin >> n >> Q;
    for (int i = 1;i <= n;i++) {
        s.insert({ i,i });
        cnt[i] = 1;
    }
    while (Q--) {
        int op;
        cin >> op;
        if (op == 1) {
            int x, c;
            cin >> x >> c;
            auto it = s.upper_bound({ x,1e9 });
            it--;//找到x位置是在哪一段
            if (it->second == c) continue;
            int ed;
            int st = it->first;//当前段左端点
            if (next(it) == s.end()) ed = n;//通过下一段的左端点计算当前段的右端点
            else ed = next(it)->first - 1;
            cnt[it->second] -= (ed - st + 1);//更新格子数
            cnt[c] += (ed - st + 1);
            vector<pair<int, int> > v;
            if (next(it) != s.end() && next(it)->second == c)//看下一段是不是颜色相同
                v.push_back(*next(it));
            if (it != s.begin() && prev(it)->second == c) {//上一段
                st = prev(it)->first;
                v.push_back(*prev(it));
            }
            s.erase(it);
            for (int i = 0;i < v.size();i++)//把颜色相同的段删掉
                s.erase(v[i]);
            s.insert({ st,c });//只保留合并的新段
        }
        else {
            int c;
            cin >> c;
            cout << cnt[c] << endl;
        }
    }
    return 0;
}

标签:AtCoder,int,Solution,cin,380,++,字符串,翻转,size
From: https://www.cnblogs.com/NightRaven/p/18579174

相关文章

  • AtCoder Beginner Contest 382 赛后复盘
    abc381的赛后总结不见了。(人话:没写)A-B模拟即可C因为好吃的会被前面的人吃掉,后面的人只能捡垃圾吃,所以实际上能吃东西的\(a\)成单调递减。所以我们直接二分在哪个区间即可,时间复杂度\(O(m\logn)\)。点击查看代码#include<bits/stdc++.h>#definelllonglong#de......
  • AtCoder Beginner Contest 382
    A-DailyCookie题意给定长为\(n\)的串,“.”代表空,“@”代表饼干,一天吃一块饼干,问\(d\)天后有几个格子是空的。思路模拟。代码点击查看代码#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongtypedefpair<int,int>pii;constintmxn=1e......
  • The solution to NOIP2024·T1——edit
    ThesolutiontoNOIP2024·T1——edithttps://www.luogu.com.cn/problem/P11361这是我在赛场想出来的思路,平时一个绿题都写不出来的题竟然一眼出思路,也真是RP++;思路由题目中的非限制的数可以互相交换,想到对于每一段连续的非限制性的区间都可以任意排布位置。那么可以把t序......
  • Atcoder Beginner Contest 330 题解
    前言过于水的一场。ACountingPasses题面给出一个长度为\(n\)的序列\(a\),求出\(a\)之中大于等于\(l\)的数个个数。\(1\len\le100,1\lea_i\le1000,1\lel\le1000\)。制約入力は全て整数$1\\le\N\\le\100$$1\\le\L\\le\1000$$0\\le\A_i\\le......
  • AtCoder Beginner Contest 381
    省流版A.按题意判断即可B.按题意判断即可C.枚举/的位置,然后分别向左右找到最长的1串和2串,然后取最小值即可D.讨论起始位置的奇偶性,然后用双指针,每两个字符每两个字符,维护出现的次数为2,两种情况取最大值即可E.答案为所有/的左右12个数的最小值的最大值,注意到个数随着/......
  • AtCoder ABC321F - #(subset sum = K) with Add and Erase 题解 可撤销背包
    题目链接:https://atcoder.jp/contests/abc321/tasks/abc321_f题目大意:给定大小为\(k\)的背包和\(q\)次操作,支持两种操作:插入一个大小为\(x\)的元素;删除一个大小为\(x\)的元素。每次操作后,求装满背包方案数。解题思路:可撤销背包。插入\(x\)时,fori=K->x......
  • Toyota Programming Contest 2024#11(AtCoder Beginner Contest 379)
    A-Cyclic链接:A-Cyclic代码:#include<bits/stdc++.h>usingnamespacestd;intmain(){ stringss; cin>>ss; cout<<ss[1]<<ss[2]<<ss[0]<<""<<ss[2]<<ss[0]<<ss[1]; return0;}B-Strawberri......
  • 【Solution】用C语言代码绘制线性函数包围图
    题目:绘制左边图的众多*输出图像,函数已给出:y=1,y=-x+2n,y=x。解决方案: 思路对于原来的坐标几何图形,2<=n,y<=x<=2n-y,1<=y<=x。我们用来写C代码的函数首先要确定三角形高的范围,至少要2。将图形分隔成上下两部分。从最高的顶点到三角形高的部分,和其下面的部分。使用line......
  • 【Atcoder训练记录】AtCoder Beginner Contest 381
    训练情况赛后反思简单题A题做红温了,怒吃6罚时,C题双指针其实差不多想出来了,但是对于判断字符串合法其实可以只判断两个端点,不需要全部遍历,中途还想了二分做法(?),然而写到最后发现并没有二分单调性。A题记得判断字符串的长度必须是奇数,\(1\sim\frac{n+1}{2}-1\)是1,\(\frac{......
  • AtCoder Beginner Contest 381
    这场比赛打的冷汗直流,然后无奈寄掉。C-11/22Substring本以为直接暴力就可以,但是需要加前缀和优化,一个正向处理,一个反向处理,然后查找/。abc381_d赛前2分钟hack掉自己的代码,然后寄掉。双指针答案必须是连续的区间,所以想到双指针维护区间合法性,但需要处理以下细节:\(a_r\n......