Deltix Round, Autumn 2021 (Div. 1 + Div. 2)

21 篇文章 0 订阅
19 篇文章 0 订阅

题目链接

补题挖坑

A

凡是有2的因子的全提出来,之后排序乘给最大的奇数

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
ll t, n;
int main()
{
    cin >> t;
    while (t--)
    {
        cin >> n;
        vector<ll> a(n);

        for (auto &i : a)
            cin >> i;

        
        int ans = 0;
        for (int i = 0; i < a.size();i++)
        {
            while(a[i]%2==0)
            {
                ans += 1;
                a[i] /= 2;
            }
        }
        sort(a.begin(), a.end());
        ll sum = 0;
        for (int i = 0; i < a.size() - 1;i++)
        {
            sum += a[i];
        }
        sum += a[n - 1] * pow(2, ans);
        cout << sum << endl;
    }
    return 0;
}
B

感觉写麻烦了,但大意就是匹配到了abc就ans++,没匹配到的话就ans不变,ans是开始遍历计算的abc数量

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
ll t, n;
int main()
{
    cin >> n >> t;
    string s;
    cin >> s;
    int ans = 0;
    for (int i = 0; i < n - 2;)
    {
        if (s[i] == 'a' && s[i + 1] == 'b' && s[i + 2] == 'c')
        {
            ans++;
            i += 3;
        }
        else
        {
            i++;
        }
    }
    s = "0" + s + "0";
    while (t--)
    {
        char c;
        int pos;
        scanf("%d %c", &pos, &c);
        if (c == s[pos])
        {
            cout << ans << endl;
            continue;
        }
        bool flag = true;
        if (s[pos] == 'a' && s[pos + 1] == 'b' && s[pos + 2] == 'c' && pos <= n - 2)
        {
            if (c != 'a')
                ans--;
        }
        else if (s[pos - 1] == 'a' && s[pos] == 'b' && s[pos + 1] == 'c')
        {
            if (c != 'b')
                ans--;
        }
        else if (s[pos - 2] == 'a' && s[pos - 1] == 'b' && s[pos] == 'c' && pos >= 2)
        {
            if (c != 'c')
                ans--;
        }
        if (c == 'a' && s[pos + 1] == 'b' && s[pos + 2] == 'c' && pos <= n - 2)
        {
            ans++;
        }
        else if (s[pos - 1] == 'a' && c == 'b' && s[pos + 1] == 'c')
        {
            ans++;
        }
        else if (s[pos - 2] == 'a' && s[pos - 1] == 'b' && c == 'c' && pos >= 2)
        {
            ans++;
        }
        cout << ans << endl;
        s[pos] = c;
    }
    return 0;
}
C

规定了间隙e,所以就是找素数,找到之后看看间隙左右的1的个数,左边是back,右边是back
只考虑单侧那就back+front
考虑左右两边就back*front
最后加和输出,但是要记得longlong

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
typedef long long ll;
ll t, n, e;
int isPrime(int n)
{
    if (n <= 1)
    {
        return 0;
    }
    for (int i = 2; i * i <= n; i++)
    {
        if (n % i == 0)
        {
            return 0;
        }
    }
    return 1;
}
int main()
{
    cin >> t;
    while (t--)
    {
        cin >> n >> e;
        vector<ll> a(n);
        for (auto &i : a)
            cin >> i;
        ll ans = 0;
        for (int i = 0; i < n; ++i)
        {
            if (isPrime(a[i]))
            {
                ll _front = 0, _back = 0;
                for (int j = i + e; j < n; j += e)
                    if (a[j] == 1)
                        _front++;
                    else
                        break;
                for (int j = i - e; j >= 0; j -= e)
                    if (a[j] == 1)
                        _back++;
                    else
                        break;
                ans += (_front + _back);
                ans += (_front * _back);
            }
        }
        cout << ans << endl;
    }
    return 0;
}
D

题目大意是给定n个点,针对m个边即时输出最大的连通块大小-1(题目定义的熟人)

如果有重复的边或者联通集和内部的边那就拿出来用作连接两个联通集和

用并查集维护就行

但感觉这样做很容易T,因为map倒vector,有双set的写法可以再看看

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
ll m, n;
int fa[1010];
int get(int x)
{
    if (x == fa[x])
        return x;
    return fa[x] = get(fa[x]);
}

void merge(int x, int y)
{
    fa[get(x)] = get(y);
}

bool cmp(pair<int,int> a,pair<int,int> b)
{
    return a.second > b.second;
}

int main()
{

    cin >> n >> m;
    for (int i = 1; i <= n; ++i)
    {
        fa[i] = i;
    }
    int flag = 0;
    int ans = 0;
    for (int i = 0; i < m; ++i)
    {
        int x, y;
        cin >> x >> y;
        if (get(x) != get(y))
            merge(x, y);
        else
        {
            flag++;
        }
        map<int, int> M;
        for (int i = 1; i <= n; ++i)
        {
            M[get(i)]++;
        }
        vector<pair<int, int>> a(M.begin(), M.end());
        sort(a.begin(), a.end(), cmp);
        ans = a[0].second;
        for (int i = 1; i <= flag && i < a.size(); ++i)
        {
            ans += a[i].second;
        }
        cout << ans - 1 << endl;
    }
    return 0;
}

E

听说是线段树,不会构造阿巴阿巴

留着空挖坑

有能力再继续补
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

数学小牛马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值