Codeforces Round 933 (Div. 3)(A~D题解)

目录

1.A. Rudolf and the Ticket

2.B. Rudolf and 121

3.C. Rudolf and the Ugly String

4.D. Rudolf and the Ball Game


1.A. Rudolf and the Ticket

Problem - A - Codeforces

暴力签到题,两次for循环搞定。

#include<iostream>
#include<set>
#include<map>
#include<string>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdlib.h>
#define ll long long
using namespace std;
const int N = 200010;
const int M = 500010;
const int inf = 1234567890;
ll a[N], b[N], c[N];
void solve()
{
    ll n, m, k;
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i++) cin >> a[i];
    for (int i = 1; i <= m; i++ ) cin >> b[i];
    ll ans = 0;
    sort(a + 1, a + 1 + n);
    sort(b + 1, b + 1 + m);
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++)
        {
            if (a[i] + b[j] <= k) ans++;
            else break;
        }
    }
    cout << ans << "\n";
}
int main()
{
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

2.B. Rudolf and 121

Problem - B - Codeforces

题意:题目给出一个数组,要求我们将这个数组的元素全部变成0,只能进行一种操作多次或者不操作。

选择一个索引r,1<r<n(数组长度),对索引位置的元素-2,旁边两元素都-1。

思路:我们发现最左边的元素的大小改变与它右边的元素有关,那我们直接遍历一遍,如果此时的元素不为0,那个它右边的元素就减去2*这个元素,它右边的右边的元素减去相同值,如果出现负数,则证明这个数组不能通过这个操作全部变成0。

AC代码:

#include<iostream>
#include<set>
#include<map>
#include<string>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdlib.h>
#define ll long long
using namespace std;
const int N = 200010;
const int M = 500010;
const int inf = 1234567890;
ll a[N], b[N], c[N];
void solve()
{
    ll n;
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];
    if (n == 3)
    {
        if (a[1] != a[3])
        {
            cout << "NO\n";
        }
        else
        {
            if (a[2] - 2 * a[1] != 0)
            {
                cout << "NO\n";
            }
            else cout << "YES\n";
        }
        return;
    }
    for (int i = 2; i <= n-1; i++)
    {
        if (a[i - 1] == 0)
            continue;
        else
        {
            a[i] -= 2 * a[i - 1];
            a[i + 1] -= a[i - 1];
            a[i - 1] = 0;
            if (a[i] < 0) break;
            if (a[i + 1] < 0) break;
        }
    }
    for (int i = 1; i <= n; i++)
    {
        if (a[i] != 0)
        {
            cout << "NO\n";
            return;
        }
    }
    cout << "YES\n";
    
}
int main()
{
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

3.C. Rudolf and the Ugly String

Problem - C - Codeforces

思路:其实就是找"map"和"pie"的个数,但是会有"mapie"的出现,这时只需删除一个即可。

AC代码:

#include<iostream>
#include<set>
#include<map>
#include<string>
#include<queue>
#include<vector>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<stdlib.h>
#define ll long long
using namespace std;
const int N = 200010;
const int M = 500010;
const int inf = 1234567890;
ll a[N], b[N], c[N];

void solve()
{
    int n;
    cin >> n;
    string s;
    cin >> s;
    int cnt1 = 0, cnt2 = 0;
    vector<int>q;
    for (int i = 0; i < n-2; i++)
    {
        if (s[i] == 'm' && s[i + 1] == 'a' && s[i + 2] == 'p') cnt1++,q.push_back(i+2);
        if (s[i] == 'p' && s[i + 1] == 'i' && s[i + 2] == 'e') cnt2++,q.push_back(i);
    }
    sort(q.begin(), q.end());
    ll ans = cnt1 + cnt2;
    for (int i = 1; i < q.size(); i++)
        if (q[i] == q[i - 1])ans--;
    cout << ans << "\n";
    
}
int main()
{
    int t;
    cin >> t;
    while (t--) {
        solve();
    }
    return 0;
}

4.D. Rudolf and the Ball Game

Problem - D - Codeforces

 

其实就是按照规律顺时针逆时针转,?保留两个进去,我在当时是使用了bfs去解决,但是内存直接暴了,看来题解才发现自己多愚蠢。

下面是AC代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <cmath>
#include <set>
 
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
 
const int N = 1e5 + 10, M = N * 2, mod = 1e9 + 7;
int T, n, m, a;
 
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    cin >> T;
    while (T--)
    {
        cin >> n >> m >> a;
        set<int> q[2]; // q[0]所有元素扩展出来的放入q[1],然后清空q[0]
        int ix = 0;    // q[1]所有元素扩展出来的放入q[0],然后清空q[1]
        q[ix].insert(a);
        while (m--)
        {
            int x;
            char ch;
            cin >> x >> ch;
            while (q[ix].size())
            {
                int u = *(q[ix].begin()); // 一边遍历一边删除,非常有用的技巧,使用for循环一遍遍历set一遍删除是不可以的,但是这里这种方式是可以的
                q[ix].erase(u);
                if (ch == '0' || ch == '?') // 顺时针
                {
                    q[ix ^ 1].insert((u + x - 1) % n + 1);
                }
                if (ch == '1' || ch == '?') // 逆时针
                {
                    q[ix ^ 1].insert((u - x - 1 + n) % n + 1);
                }
            }
            ix ^= 1; // 采取异或操作,只需要使用一个大小为2的set维护即可,相比直接使用2个set,这种写法非常巧妙,可以减少代码量
        }
        cout << q[ix].size() << '\n'; // 此时的q[ix]就是最终可以扩展出来的所有位置
        for (auto &t : q[ix])
        {
            cout << t << ' ';
        }
        cout << '\n';
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值