Codeforces Round 898 (Div. 4)

发布时间 2023-09-22 13:56:46作者: value0

Codeforces Round 898 (Div. 4)

A. Short Sort

解题思路:

遍历所有交换情况,看是否有\(abc\).

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;
void solve()
{
    string s;
    cin >> s;
    string a = s;
    swap(a[0], a[1]);
    string b = s;
    swap(b[0], b[2]);
    string c = s;
    swap(c[1], c[2]);
    string t = "abc";
    if (s == t || a == t || b == t || c == t)
    {
        puts("YES");
    }
    else
    {
        puts("NO");
    }
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

B. Good Kid

解题思路:

将最小的数字加一.

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;
void solve()
{
    scanf("%d", &n);
    vector<int> a(n + 1);
    int idx = 0;
    int res = 12312;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        if (a[i] < res)
        {
            res = a[i];
            idx = i;
        }
    }
    a[idx]++;
    ll ans = 1;
    for (int i = 1; i <= n; i++)
    {
        ans *= (ll)a[i];
    }
    printf("%lld\n", ans);
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

C. Target Practice

解题思路:

由于图是固定的,暴力判断每个击中的点属于哪一类即可。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;
char g[100][100];
void solve()
{
    for (int i = 1; i <= 10; i++)
    {
        scanf("%s", g[i] + 1);
    }
    n = 10;
    ll ans = 0;
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            if (g[i][j] == 'X')
            {
                if (i == 1 || i == 10)
                {
                    ans += 1;
                }
                else if (i == 2 || i == 9)
                {
                    if (j == 1 || j == 10)
                    {
                        ans += 1;
                    }
                    else
                    {
                        ans += 2;
                    }
                }
                else if (i == 3 || i == 8)
                {
                    if (j == 1 || j == 10)
                    {
                        ans += 1;
                    }
                    else if (j == 2 || j == 9)
                    {
                        ans += 2;
                    }
                    else
                    {
                        ans += 3;
                    }
                }
                else if (i == 4 || i == 7)
                {
                    if (j == 1 || j == 10)
                    {
                        ans += 1;
                    }
                    else if (j == 2 || j == 9)
                    {
                        ans += 2;
                    }
                    else if (j == 3 || j == 8)
                    {
                        ans += 3;
                    }
                    else
                    {
                        ans += 4;
                    }
                }
                else if (i == 5 || i == 6)
                {
                    if (j == 1 || j == 10)
                    {
                        ans += 1;
                    }
                    else if (j == 2 || j == 9)
                    {
                        ans += 2;
                    }
                    else if (j == 3 || j == 8)
                    {
                        ans += 3;
                    }
                    else if (j == 4 || j == 7)
                    {
                        ans += 4;
                    }
                    else
                    {
                        ans += 5;
                    }
                }
            }
        }
    }
    printf("%lld\n", ans);
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

D. 1D Eraser

解题思路:

从左往右遍历,遇到一个\(B\)就以他为起点向右染白即可。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;

void solve()
{
    scanf("%d %d", &n, &k);
    string s;
    cin >> s;
    int cnt = 0;
    for (int i = 0; i < n; i++)
    {
        if (s[i] == 'B')
        {
            cnt++;
            int j = 0;
            for (j = i; j <= i + k - 1; j++)
            {
                s[i] = 'W';
            }
            j--;
            i = j;
        }
    }
    printf("%d\n", cnt);
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

E. Building an Aquarium

解题思路:

二分高度,暴力判断。

注意本题二分边界,最小取到1。

由于答案上界为\(2\times 10^9\),\(n = 1,a[1] = 10^9,x = 10^9\)

右边界也别取太大,如\(10^{18}\),二分过程会爆\(long \ long\)

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;

void solve()
{
    scanf("%d %d", &n, &k);
    vector<ll> a(n + 1);
    for (int i = 1; i <= n; i++)
    {
        scanf("%lld", &a[i]);
    }
    ll l = 1;
    ll r = 3e9;
    auto check = [&](ll h)
    {
        ll sum = 0;
        for (int i = 1; i <= n; i++)
        {
            sum += max(0ll, h - a[i]);
        }
        if (sum > k)
        {
            return false;
        }
        else
        {
            return true;
        }
    };
    while (l + 1 < r)
    {
        ll mid = l + r >> 1;
        if (check(mid))
        {
            l = mid;
        }
        else
        {
            r = mid;
        }
    }
    printf("%lld\n", l);
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

F. Money Trees

解题思路:

类似滑动窗口。

从左往右遍历,在线记录以\(i\)为最后一个元素,向左最长可以选择多少元素。

用前缀和计算当前最大区间和。

若区间和大于限制,那么从左端点开始一个个删去,直至区间和合法。此时区间长度就是以第\(i\)个元素为结尾的最长区间。

全局答案就是所有最长区间中的最大值。

注意:左右端点可以相等。

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;

void solve()
{
    scanf("%d %d", &n, &k);
    vector<int> a(n + 1), h(n + 1), b(n + 1);
    vector<ll> s(n + 1);
    vector<pii> v;
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &a[i]);
        s[i] = a[i] + s[i - 1];
    }
    for (int i = 1; i <= n; i++)
    {
        scanf("%d", &h[i]);
    }
    ll ans = 0;
    int idx = 0;
    for (int i = 1; i <= n; i++)
    {
        if (i == 1)
        {
            b[i] = 0;
        }
        else if (h[i - 1] % h[i] == 0)
        {
            b[i] = b[i - 1] + 1;
        }
        else
        {
            b[i] = 0;
            // continue;
        }
        int l = max(i - b[i], idx);
        int r = i;
        ll res = s[r] - s[l - 1];
        if (res <= k)
        {
            // cout << i << ' ' << (r - l + 1) << endl;
            ans = max(ans, r - l + 1ll);
        }
        else
        {
            while (res > k)
            {
                res -= a[l];
                l++;
            }
            idx = l;
            ans = max(ans, r - l + 1ll);
        }
    }
    printf("%lld\n", ans);
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}

G .ABBC or BACB

解题思路:

我们可以将连续的\(A\)看成\(A\)块。

我们发现,一个\(B\)无论在\(A\)块的左边还是右边,都可以对整个\(A\)块进行连续操作,此时对答案的贡献就是块中\(A\)的个数\(res\)

所以,我们统计\(A\)块的数量\(cnt_a\),同时统计与\(A\)块相邻的\(B\)的数量\(cnt_b\)

如果\(cnt_b >= cnt_a\),那么答案就是\(res\).

否则,答案就是\(res-最小的A块中的A的数量\)。因为\(A\)块就是由\(B\)分割而来,\(min(cnt_b) = cnt_a - 1\)

代码:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int N = 1e6 + 10;
const int M = 2 * M;
typedef pair<int, int> pii;
#define fi first
#define se second
int n, m, k;

void solve()
{
    string s;
    cin >> s;
    n = s.size();
    s = ' ' + s;
    int ans = 0;
    int cnt = 0;
    int res = 0;
    vector<int> v;
    for (int i = 1; i <= n; i++)
    {
        char c = s[i];
        if (c == 'A')
        {
            cnt++;
        }
        else
        {
            if (s[i - 1] == 'A' || s[i + 1] == 'A')
            {
                res++;
            }
            if (cnt)
            {
                v.push_back(cnt);
                ans += cnt;
            }
            cnt = 0;
        }
    }
    if (cnt)
    {
        v.push_back(cnt);
        ans += cnt;
    }
    sort(v.begin(), v.end());
    if (res < v.size())
    {
        if (!v.empty())
        {
            ans -= v[0];
        }
    }
    printf("%d\n", ans);
}

int main()
{
    int t = 1;
    scanf("%d", &t);
    while (t--)
    {
        solve();
    }
    return 0;
}