ABC364

A

题意: 有两种食物,甜的与咸的,可以连续吃多次咸的,但是连续吃两次甜的食物就吃不下了,按照给出的顺序吃食物,问是否能吃完所有食物。

题解: 记录一下当前吃了几个甜的,如果已经吃了两次甜的,并且不是最后一份食物,那么就是 N o No No

#include<bits/stdc++.h>
using namespace std;

#define fir first
#define sec second
#define endl "\n"   

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll, ll> pll;
const int N = 1e5 + 10, M = N * 2, mod = 1e9 + 7, inf = 0x3f3f3f3f, P = 131;

void solve()
{
    int n;
    cin >> n;
    int cnt = 0;
    bool is_suc = true;
    for(int i = 0; i < n; i ++)
    {
        string s;
        cin >> s;
        if(s == "sweet")
            cnt ++;
        else
            cnt = 0;

        if(cnt == 2 and i != n - 1)
            is_suc = false;
    }
    if(is_suc)
        cout << "Yes" << endl;
    else
        cout << "No" << endl;

}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

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

    return 0;
}

B

题意: 有一个 n ∗ m n * m nm的迷宫, ′ . ′ '.' .可以移动, ′ # ′ '\#' #是墙壁。给出起点和移动方式,如果可以移动则移动,无法移动则呆在原地。

题解: 按照题意模拟就行了。

#include<bits/stdc++.h>
using namespace std;

#define fir first
#define sec second
#define endl "\n"   

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll, ll> pll;
const int N = 1e5 + 10, M = N * 2, mod = 1e9 + 7, inf = 0x3f3f3f3f, P = 131;

void solve()
{
    int n, m;
    cin >> n >> m;
    int x, y;
    cin >> x >> y;
    vector<string> g(n + 1);
    for(int i = 1; i <= n; i ++)
        cin >> g[i], g[i] = " " + g[i];

    string str;
    cin >> str;
    for(auto t : str)
    {
        if(t == 'U' and x > 1 and g[x - 1][y] != '#')
            x --;
        else if(t == 'D' and x < n and g[x + 1][y] != '#')
            x ++;
        else if(t == 'L' and y > 1 and g[x][y - 1] != '#')
            y --;
        else if(t == 'R' and y < m and g[x][y + 1] != '#')
            y ++;
    }
    cout << x << " " << y << endl;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

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

    return 0;
}

C

题意: 每份食物有甜度与咸度,你可以任意顺序吃食物,如果吃的甜度超过 X X X或者咸度超过 Y Y Y,就停止吃食物,最少吃多少份食物。

题解: 根据甜度和咸度分别排序,每次都吃尽可能大的。注意一下,可以正好等于 X , Y X,Y XY

#include<bits/stdc++.h>
using namespace std;

#define fir first
#define sec second
#define endl "\n"   

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll, ll> pll;
const int N = 1e5 + 10, M = N * 2, mod = 1e9 + 7, inf = 0x3f3f3f3f, P = 131;

void solve()
{
    ll n, x, y;
    cin >> n >> x >> y;
    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];

    sort(a.begin() + 1, a.end(), greater<int>());
    int cnt1 = 0;
    for(int i = 1; i <= n; i ++)
    {
        cnt1 ++;
        x -= a[i].fir;
        if(x < 0)
            break;
    }
    sort(b.begin() + 1, b.end(), greater<int>());
    int cnt2 = 0;
    for(int i = 1; i <= n; i ++)
    {
        cnt2 ++;
        y -= a[i].sec;
        if(y < 0)
            break;
    }

    cout << min(cnt1, cnt2) << endl;
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

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

    return 0;
}

D

题意: 一个长度 n n n的数组 a a a,和 q q q次提问。每次提问给出 b b b k k k。然后把这个 b b b和数组 a a a做一个计算。可以算出距离 d i d_i di。将所有的 d i d_i di排序(升序),求 d k d_k dk的值。

题解: 1 ≤ n , q ≤ 1 0 5 1 \leq n, q \leq 10^5 1n,q105,如果每次提问都真的计算一遍的话,时间复杂度会非常大,于是考虑二分答案。那么如果 a a a数组在 [ b − x , b + x ] [b - x, b + x] [bx,b+x]之间的个数是大于 k k k,那么就需要缩小 x x x,否则增大 x x x,使得 a a a数组在区间 [ b − x , b + x ] [b - x, b + x] [bx,b+x]中的个数恰好 k k k个。

顺便附上我常用的二分模板的出处,我觉得讲的比yxc讲得好,大家可以听一下:【二分查找为什么总是写错?】

#include<bits/stdc++.h>
using namespace std;

#define fir first
#define sec second
#define endl "\n"   

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll, ll> pll;
const int N = 1e5 + 10, M = N * 2, mod = 1e9 + 7, inf = 0x3f3f3f3f, P = 131;

void solve()
{
    int n, q;
    cin >> n >> q;
    vector<int> a(n + 1);
    for(int i = 1; i <= n; i ++)
        cin >> a[i];
    sort(a.begin() + 1, a.end());
    //二分的前提,数组有序

    while(q --)
    {
        int b, k;
        cin >> b >> k;
        int l = -1, r = 1e9 + 1;
        while(l + 1 != r) //二分模板,看一下视频理解
        {
            auto check = [&](int x)
            {
                int p1 = lower_bound(a.begin() + 1, a.end(), b - x) - a.begin();
                //找出b - x的位置
                int p2 = upper_bound(a.begin() + 1, a.end(), b + x) - a.begin();
              	//找出b + x的位置。
			   /*
			   lower_bound(起点,终点,数字) - 起点
                lower_bound和upper_bound的用法很多,可以找出下标,可以直接找到数字。
                python中应该也有对应的函数
                lower_bound是在给出的范围内,找到第一个大于等于所求数字的数字。
                upper_bound是在给出的范围内,找到第一个大于所求数字的数字。
                */
                if(p2 - p1 + 1 > k)
                    return 1;
                return 0;
            };
            int mid = l + r >> 1;
            if(check(mid))
                r = mid;
            else
                l = mid;
        }
        cout << r << endl;
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

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

    return 0;
}
  • 15
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值