2024牛客寒假算法基础集训营5

A

void solve()
{
    int n;
    cin >> n;
    int cnt = 0;
    for (int i = 1; i <= n; i++)
    {
        int x;
        cin >> x;
        if (x == 1)
            cnt++;
    }
    cout << n - cnt << endl;
}

B

答案可能是

m_y_g_o

ll f[N][N][N];
void solve()
{
    string s;
    cin >> s;
    int n = s.size();
    s = '#' + s;
    vector<ll> f(n + 10, 0);
    f[0] = 1, f[1] = 2, f[2] = 3, f[3] = 5;
    for (int i = 4; i <= n; i++)
        f[i] = (f[i - 1] + f[i - 2]) % mod;
    ll ans = 0;
 
    for (int i = 4; i <= n; i++)
        if (s[i] == 'o')
            for (int j = i - 1; j >= max(1, i - 2); j--)
                if (s[j] == 'g')
                    for (int k = j - 1; k >= max(1, j - 2); k--)
                        if (s[k] == 'y')
                            for (int l = k - 1; l >= max(1, k - 2); l--)
                                if (s[l] == 'm')
                                {
                                    // cout << l << " " << k << " " << j << " " << l << endl;
                                    ans = (ans + f[l - 1] * f[n - i] % mod) % mod;
                                }
    cout << ans << endl;
}

C

每次放一个0,都会使得两边数-1

void solve()
{
    ll n, ans = 0;
    cin >> n;
    vector<ll> a(n + 2, 0);
    a[0] = 1e10, a[n + 1] = 1e10;
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    for (int i = 1; i <= n + 1; i++)
    {
        ll sub = min(a[i] - 1, a[i - 1] - 1);
        ans += sub;
        a[i] -= sub;
    }
    cout<<ans<<endl;
}

D

E

偶数一定可以

奇数贪心,使得每个偶数位置a[i]尽可能大且满足\(a[i]\le a[i+1]\)

检查是否满足即可

void solve()
{
    int n;
    cin >> n;
    vector<ll> a(n + 1);
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    if (n % 2 == 0)
    {
        cout << "YES" << endl;
        return;
    }
    else
    {
        ll tot = 0;
        for (int i = n - 1; i >= 1; i -= 2)
        {
            a[i] += tot * i;
            a[i - 1] += tot * (i - 1);
            if (a[i] > a[i + 1])
            {
                cout << "NO" << endl;
                return;
            }
            ll cnt = (a[i + 1] - a[i]) / i;
            tot += cnt;
            a[i] += cnt * i, a[i - 1] += cnt * (i - 1);
            if (a[i - 1] > a[i])
            {
                cout << "NO" << endl;
                return;
            }
        }
        cout << "YES" << endl;
    }
}

F

偶数就是\(a[i-1]-a[i]\)差值最大的,只需要操作n位置即可

奇数重复e的贪心过程,每次变大的时候与\(a[i-1]-a[i]\)的max取min即可

void solve()
{
    int n;
    cin >> n;
    vector<ll> a(n + 1);
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    ll mx = 0, ans = 0;
    for (int i = 2; i <= n; i++)
        mx = max(mx, a[i - 1] - a[i]);
    ans = mx;
    if (n % 2)
    {
        ans = 0;
        ll tot = 0;
        for (int i = n - 1; i >= 1; i -= 2)
        {
            a[i] += tot * i;
            a[i - 1] += tot * (i - 1);
            if (a[i] > a[i + 1])
            {
                cout << "-1" << endl;
                return;
            }
            ll cnt = min((a[i + 1] - a[i]) / i, mx);
            mx -= cnt, ans += cnt;
            tot += cnt;
            a[i] += cnt * i, a[i - 1] += cnt * (i - 1);
            if (a[i - 1] > a[i])
            {
                cout << "-1" << endl;
                return;
            }
        }
    }
    cout << ans << endl;
}

G/H

暴力打表发现存在一个递增的p[i]+i,并且是将1,2,3,4...分割成若干段后反转得到的,暴力枚举即可

void solve()
{
    vector<int> pr;
    vector<bool> not_pr(N);
    auto getpr = [&](int n)
    {
        for (int i = 2; i <= n; ++i)
        {
            if (!not_pr[i])
                pr.push_back(i);
            for (int p : pr)
            {
                if (i * p > n)
                    break;
                not_pr[i * p] = true;
                if (i % p == 0) // 说明i*p已经被一个更小的i判断过了
                    break;
            }
        }
    };
    getpr(2e6);
    int n;
    cin >> n;
    vector<int> ans(n + 1);
    for (int i = 1; i <= n; i++)
        ans[i] = i;
    int r = n;
    for (int i = n; i >= 1; i--)
    {
        if (!not_pr[i + r])
        {
            for (int j = r, k = i; j >= k; j--, k++)
                swap(ans[j], ans[k]);
            r = i - 1;
        }
    }
    for (int i = 1; i <= n; i++)
        cout << ans[i] << " ";
    cout << endl;
}

I

分类讨论

void solve()
{
    ll t, a, k;
    cin >> t >> a >> k;
    ll l = 0, r = t;
    if (l > r)
        swap(l, r);
    l -= k, r += k;
    if (a >= l && a <= r)
        cout << abs(a) + abs(t - a) << endl;
    else
        cout << abs(t) + 2 * abs(t - a) << endl;
}

J

三分:

void solve()
{
    ll n;
    cin >> n;
    vector<pll> seg(n);
    for (auto &[l, r] : seg)
        cin >> l >> r;
    auto f = [&](int x) -> ll
    {
        ll res = 0;
        for (int i = 0; i < n; i++)
            if (x < seg[i].x)
                res += seg[i].x - x, x = seg[i].x;
            else if (x > seg[i].y)
                res += x - seg[i].y, x = seg[i].y;
        return res;
    };
    int l = seg[0].x, r = seg[0].y;
    for(int i=0;i<=60;i++)
    {
 
        int lmid = l + (r - l) / 3;
        int rmid = r - (r - l) / 3;
        if (f(lmid) < f(rmid))
            r = rmid;
        else
            l = lmid;
    }
    ll ans = 1e18;
    for (int i = l; i <= r; i++)
        ans = min(ans, f(i));
    cout << ans << endl;
}

贪心:

void solve()
{
    int n, l, r;
    cin >> n;
    cin >> l >> r;
    ll ans = 0;
    for (int i = 1; i < n; i++)
    {
        int x, y;
        cin >> x >> y;
        if (x > r)
        {
            ans += x - r;
            l = r = x;
        }
        else if (y < l)
        {
            ans += l - y;
            l = r = y;
        }
        else
        {
            l = max(l, x), r = min(r, y);
        }
    }
    cout << ans << endl;
}

K

类似完全背包

void solve()
{
    ll n, p;
    cin >> n >> p;
    vector<ll> f(n + 1, 1e10);
    f[0] = 0;
    for (int i = 1; i <= n; i++)
    {
        ll a, b;
        cin >> a >> b;
        b = min(b, n - 1);
        for (int i = 0; i < n; i++)
            f[i] = min(f[i], f[max(0ll, i - b)] + a);
    }
    ll ans = 1e10;
    for (int i = 0; i < n; i++)
        ans = min(ans, f[i] + (n - i) * p);
    cout << ans << endl;
}

L

void solve()
{
    int n, x;
    cin >> n >> x;
 
    for (int i = 0; i <= n ; i++)
    {
        if (n - (2 * i )== x)
        {
            cout << n - i << " " << i << endl;
            return;
        }
    }
    cout << "-1" << endl;
}

M

分类讨论

void solve()
{
    int n;
    cin >> n;
    vector<int> a(n + 1), b(n + 1);
    for (int i = 1; i <= n; i++)
        cin >> a[i];
    for (int i = 1; i <= n; i++)
        cin >> b[i];
    if (n == 1)
        cout << "-1" << endl;
    else if (n == 2)
    {
        for (int i = 1; i <= n; i++)
            if (a[i] == b[i])
            {
                cout << "-1" << endl;
                return;
            }
        cout << "1" << endl;
    }
    else
    {
        if (a[1] == b[2] || a[n] == b[n - 1])
        {
            cout << "1" << endl;
            return;
        }
        for (int i = 2; i <= n - 1; i++)
        {
            for (int j = i - 1; j <= i + 1; j++)
                if (a[i] == b[j])
                {
                    cout << "1" << endl;
                    return;
                }
        }
        cout << "2" << endl;
    }
}
posted @ 2024-02-27 15:13  0x3ea  阅读(6)  评论(0编辑  收藏  举报