Hello 2023题解

文章包含四个编程挑战,涉及字符串处理、奇偶数序列构造及数组操作。A题是寻找字符串中L和R的位置并判断是否需要交换;B题讨论特定条件下的数字序列构造;C题利用堆解决前缀和问题;D题通过单调栈解决理发问题,判断是否能用有限数量的剃刀完成理发。
摘要由CSDN通过智能技术生成

A. Hall of Fame

寻找最后一个LR 的位置,然后判断是否交换即可

#include <bits/stdc++.h>
using namespace std;
// #define int long long
#define endl '\n'

void solve()
{
    int n;
    cin >> n;
    string s;
    cin >> s;
    int num[2]{-1, -1};
    for (int i = 0; i < n; ++i)
    {
        num[s[i] == 'R'] = i;
    }
    if (num[0] == -1 || num[1] == -1)
        cout << -1 << endl;
    else
    {
        if (num[0] < num[1])
            cout << num[0] + 1 << endl;
        else
            cout << 0 << endl;
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    int t = 1;
    cin >> t;
    while (t--)
        solve();

    return 0;
}

B. MKnez’s ConstructiveForces Task

n = 3 n=3 n=3时,输出 N O NO NO

当n为奇数时,循环输出 ( n − 3 ) / 2 和 ( n − 2 ) / 2 (n - 3) / 2和(n - 2) / 2 (n3)/2(n2)/2即可

当n为偶数时,循环输出 1 和 − 1 1和-1 11即可

#include <bits/stdc++.h>
using namespace std;
// #define int long long
#define endl '\n'

void solve()
{
    int n;
    cin >> n;
    if (n == 3)
        cout << "NO" << endl;
    else
    {
        cout << "YES" << endl;
        if (n & 1)
        {
            int t = n / 2;
            for (int i = 0; i < n; ++i)
            {
                if (i & 1)
                    cout << t * (-1) << ' ';
                else
                    cout << t - 1 << ' ';
            }
        }
        else
        {
            for (int i = 0; i < n; ++i)
                if (i & 1)
                    cout << -1 << ' ';
                else
                    cout << 1 << ' ';
        }
        cout << endl;
    }
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    int t = 1;
    cin >> t;
    while (t--)
        solve();

    return 0;
}

C. Least Prefix Sum

利用大根堆和小根堆即可

从m往前不断加,如果 a m + a m − 1 + . . . . . . + a k > 0 ( k < m ) a_m+a_{m-1}+......+a_k>0(k < m) am+am1+......+ak>0(k<m)时,将 a k − m a_{k-m} akm中的最大值乘上-1,并将操作次数+1

从m+1不断往后加,如果 a m + a m + 1 + . . . . . . a k < 0 ( m < k ) a_m+a_{m + 1}+......a_k<0(m<k) am+am+1+......ak<0(m<k)时,将 a m − k a_{m-k} amk中放任最小值乘上-1,并将操作次数+1

#include <bits/stdc++.h>
using namespace std;
// #define int long long
#define endl '\n'
#define vint vector<int>
#define ll long long

void solve()
{
    int n, m;
    cin >> n >> m;
    vint a(n + 1);
    for (int i = 1; i <= n; ++i)
        cin >> a[i];

    ll res = 0;
    int ans = 0;
    priority_queue<int,vector<int>,less<int>>q;
    for (int i = m; i > 1; --i)
    {
    	q.push(a[i]);
    	res += a[i];
        if (res > 0)
        {
        	res -= 2 * q.top();
        	q.pop();
        	ans++;
        }
    }
    res = 0;
    priority_queue<int,vector<int>,greater<int>> p;
    for (int i = m + 1; i <= n; ++i)
    {
    	p.push(a[i]);
    	res += a[i];
        if (res < 0)
        {
        	res -= 2 * p.top();
        	p.pop();
        	ans++;
        }
    }

    cout << ans << endl;
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    int t = 1;
    cin >> t;
    while (t--)
        solve();

    return 0;
}

D. Boris and His Amazing Haircut

首先读入的时候判断,如果 b i > a i b_i>a_i bi>ai,则输出 N O NO NO

随后利用map将所有的剃刀数量存入

然后从前往后扫描一遍,利用单调栈来存储头发的长度,每次将小于当前长度的头发弹出。如:

7 9 4 5 3 3 3 6 8 10 3 2 5
5 3 1 5 3 2 2 5 8 5 1 1 5

以上样例,我们先是将5,3,1依次存入栈当中,剃刀5,3,1依次消耗掉1个。然后下一个遇到的长度是5,依次将1,3弹出栈。由于此时与栈顶元素相同,不消耗剃刀。同理,如此将所有的元素扫描一遍。如果遇到剃刀数量不够的情况,则输出 N O NO NO

扫描完之后输出 Y E S YES YES

#include <bits/stdc++.h>
using namespace std;
// #define int long long
#define endl '\n'
#define ll long long
#define vint vector<int>

void solve()
{
    int n;
    cin >> n;
    vint a(n), b(n);
    for (int i = 0; i < n; ++i)
        cin >> a[i];
    bool f = true;
    for (int i = 0; i < n; ++i)
    {
        cin >> b[i];
        if(b[i] > a[i])
        	f = false;
    }
    int m;
    cin >> m;
    map<int, int> num;
    for (int i = 0, c; i < m; ++i)
    {
        cin >> c;
        num[c]++;
    }
    if (f == false)
    {
        puts("NO");
        return;
    }
    stack<int> s;
    for (int i = 0; i < n; ++i)
    {
        while (s.size() && s.top() < b[i])
            s.pop();
        if (a[i] > b[i])
        {
            if (s.empty() || s.top() != b[i])
            {
                if (num[b[i]] > 0)
                {
                    num[b[i]]--;
                    s.push(b[i]);
                }
                else
                {
                    puts("NO");
                    return;
                }
            }
        }
    }
    puts("YES");
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    int t = 1;
    cin >> t;
    while (t--)
        solve();

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值