Codeforces Round 920 (Div. 3)

Codeforces Round 920 (Div. 3)

A - Square

解题思路:

取左下角和右上角。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;

void solve()
{
    int x1 = 1e9;
    int x2 = -1e8;
    int y1 = 1e9;
    int y2 = -1e8;
    int x, y;
    for (int i = 1; i <= 4; i++)
    {
        cin >> x >> y;
        x1 = min(x, x1);
        y1 = min(y, y1);
        x2 = max(x, x2);
        y2 = max(y, y2);
    }
    // cout << x1 << ' ' << y1 << ' ' << x2 << ' ' << y2 << endl;
    cout << (x2 - x1) * (y2 - y1) << endl;
}

int main()
{
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

B - Arranging Cats

解题思路:

统计不匹配的\(1\)的数量。多删少添。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;

void solve()
{
    int n;
    cin >> n;
    string s, f;
    cin >> s;
    cin >> f;
    ll a = 0;
    ll b = 0;
    for (int i = 0; i < n; i++)
    {
        if (s[i] == '1' && f[i] == '0')
        {
            a++;
        }
        if (s[i] == '0' && f[i] == '1')
        {
            b++;
        }
    }
    if (a >= b)
    {
        cout << a << endl;
    }
    else
    {
        cout << b << endl;
    }
}

int main()
{
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

C - Sending Messages

解题思路:

对于每一步,要么直接冲,要么关机再开机,枚举即可。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;

void solve()
{
    ll n, f, a, b;
    cin >> n >> f >> a >> b;
    vector<int> m(n + 1);
    for (int i = 1; i <= n; i++)
    {
        cin >> m[i];
    }
    ll cur = 0;
    for (int i = 1; i <= n; i++)
    {
        ll dist = m[i] - cur;
        if (dist * a <= b)
        {
            f -= dist * a;
        }
        else
        {
            f -= b;
        }
        if (f <= 0)
        {
            puts("NO");
            return;
        }
        cur = m[i];
    }
    puts("YES");
}

int main()
{
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

D - Very Different Array

解题思路:

对于每次选取,取\(a\)中最大最小和\(b\)中最大最小分别进行组合。取差最大的组。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;

void solve()
{
    ll n, m;
    cin >> n >> m;
    vector<ll> a(n + 1), b(m + 1);
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    for (int i = 1; i <= m; i++)
    {
        cin >> b[i];
    }
    sort(a.begin() + 1, a.end());
    sort(b.begin() + 1, b.end());
    ll ans = 0;
    int la = 1;
    int ra = n;
    int lb = 1;
    int rb = m;
    while (n--)
    {
        ll t1 = 0;
        ll t2 = 0;
        int ta = -1;
        int tb = -1;
        if (abs(a[la] - b[lb]) > abs(a[ra] - b[lb]))
        {
            t1 = abs(a[la] - b[lb]);
            ta = 1;
        }
        else
        {
            t1 = abs(a[ra] - b[lb]);
            ta = 0;
        }
        if (abs(a[la] - b[rb]) > abs(a[ra] - b[rb]))
        {
            t2 = abs(a[la] - b[rb]);
            tb = 1;
        }
        else
        {
            t2 = abs(a[ra] - b[rb]);
            tb = 0;
        }
        if (t1 > t2)
        {
            ans += t1;
            if (ta)
            {
                la++;
                lb++;
            }
            else
            {
                ra--;
                lb++;
            }
        }
        else
        {
            ans += t2;
            if (tb)
            {
                la++;
                rb--;
            }
            else
            {
                ra--;
                rb--;
            }
        }
    }
    cout << ans << endl;
}

int main()
{
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

E - Eat the Chip

解题思路:

如果开始就注定碰不到,那么就是平局。

\(x\)差为奇数,那么就是\(B\)尽量寻求平局,\(A\)求胜。即\(B\)尽量往墙边跑。

\(x\)差为偶数,那么就是\(A\)尽量寻求平局,\(B\)求胜。即\(A\)尽量往墙边跑。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;

void solve()
{
    ll h, w, xa, ya, xb, yb;
    cin >> h >> w >> xa >> ya >> xb >> yb;
    if (xa >= xb)
    {

        puts("Draw");
        return;
    }
    else
    {
        if (abs(xa - xb) < abs(ya - yb))
        {
            puts("Draw");
            return;
        }
        ll d = abs(xa - xb);
        if (d & 1)
        {
            if (abs(ya - yb) > 1)
            {
                if (ya < yb)
                {
                    ll t = w - yb;
                    d -= 2 * t;
                    // cout << abs(ya - yb) << ' ' << t << endl;
                    if (abs(ya - yb) > (d + 1) / 2)
                    {
                        puts("Draw");
                        return;
                    }
                    else
                    {
                        puts("Alice");
                        return;
                    }
                }
                else
                {
                    ll t = yb - 1;
                    d -= 2 * t;
                    // cout << t << endl;
                    if (abs(ya - yb) > (d + 1) / 2)
                    {
                        // cout << 1 << endl;
                        puts("Draw");
                        return;
                    }
                    else
                    {
                        puts("Alice");
                        return;
                    }
                }
            }
            else
            {
                puts("Alice");
                return;
            }
        }
        else
        {
            if (abs(ya - yb) >= 1)
            {
                if (ya < yb)
                {
                    ll t = ya - 1;
                    d -= 2 * t;
                    if (abs(ya - yb) > (d) / 2)
                    {
                        puts("Draw");
                        return;
                    }
                    else
                    {
                        puts("Bob");
                        return;
                    }
                }
                else
                {
                    ll t = w - ya;
                    d -= 2 * t;
                    if (abs(ya - yb) > (d) / 2)
                    {
                        puts("Draw");
                        return;
                    }
                    else
                    {
                        puts("Bob");
                        return;
                    }
                }
            }
            else
            {
                puts("Bob");
                return;
            }
        }
    }
}

int main()
{
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}

F - Sum of Progression

解题思路:

根号分治。

\(pre[d][i]:跳跃间隔为d时,从左到右到达第i位时的前缀和。\)

\(sum[d][i]:跳跃间隔为d时,从左到右到达第i位时的带权前缀和。权值为,当前位置为从左到右跳跃到的第几项。\)

\(pre[d][i] = \sum\limits_{idx = 1}^{\lceil\frac{i}{d}\rceil}a[i]\)

\(sum[d][i] = \sum\limits_{idx = 1}^{\lceil\frac{i}{d}\rceil} (idx \times a[i])\)

举例:

\(s = 4,d = 3,k = 3\)

\(a[4] + 2 * a[7] + 3 * a[10]\)

\(sum[3][1] = a[1]\)

\(sum[3][10] = a[1] + 2 * a[4] + 3 * a[7] + 4 * a[10]\)

\(sum[3][10] - sum[3][1] = 2 * a[4] + 3 * a[7] + 4 * a[10]\)

\(ans = sum[3][10] - sum[3][1] - 1 * (pre[3][10] - pre[3][1])\)

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<ll, ll>;
#define fi first
#define se second
using i128 = __int128_t;
const int N = 1e5 + 10;
const int lim = sqrt(N);
void solve()
{
    int n, q;
    cin >> n >> q;
    vector<ll> a(n + 1);
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i];
    }
    vector<vector<ll>> sum(lim + 10, vector<ll>(n + 10)), pre(lim + 10, vector<ll>(n + 10));
    for (int d = 1; d <= lim; d++)
    {
        for (int i = 1; i <= n; i++)
        {
            pre[d][i] = pre[d][max(i - d, 0)] + a[i];
            sum[d][i] = sum[d][max(i - d, 0)] + a[i] * ((i + d - 1) / d);
        }
    }
    while (q--)
    {
        ll s, d, k;
        scanf("%lld %lld %lld", &s, &d, &k);
        ll ans = 0;
        if (d >= lim)
        {
            ll cnt = 1;
            while (k--)
            {
                ans += cnt * a[s];
                s += d;
                cnt++;
            }
        }
        else
        {
            int r = s + (k - 1) * d;
            ans = sum[d][r] - sum[d][max(s - d, 0ll)] - ((s + d - 1) / d - 1) * (pre[d][r] - pre[d][max(s - d, 0ll)]);
        }
        cout << ans << ' ';
    }
    cout << endl;
}

int main()
{
    int t = 1;
    cin >> t;
    while (t--)
    {
        solve();
    }
    return 0;
}
posted @ 2024-01-18 16:09  value0  阅读(22)  评论(0)    收藏  举报