Codeforces Round 984 (Div. 3) A-E

链接:Codeforces Round 984 (Div. 3)

A:Quintomania

大意:

        相邻数差的绝对值是否全是5或7

思路:

        直接求

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define  vi vector<int>
#define  vii vector<pair<int, int>>
#define ff first 
#define ss second 
// ++   ~!    */+-    <<>>    <>  ==   &^|   &&|| =

void solve()
{
    int n;cin >> n;
    vi a(n);
    for (int i = 0; i < n; i++)cin >> a[i];
    for (int i = 1; i < n; i++)
    {
        int num = abs(a[i] - a[i - 1]);
        if (num != 5 && num != 7)
        {
            cout << "NO" << endl;
            return;
        }
    }
    cout << "YES" << endl;
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) solve();

    return 0;
}
/*   /\_/\
*   (= ._.)
*   / >  \>
*/

 B:Startup

大意:

        往货架里放饮料,同种放一起,问取k个货架的最大价值

思路:

        把每种的累计一下,然后就从大到小加到ans里面

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define  vi vector<int>
#define  vii vector<pair<int, int>>
#define ff first 
#define ss second 
// ++   ~!    */+-    <<>>    <>  ==   &^|   &&|| =

void solve()
{
    int n, k;cin >> n >> k;
    map<int, int>mp;
    for (int i = 1; i <= k; i++)
    {
        int a, b;cin >> a >> b;
        mp[a] += b;
    }
    vi v;
    for (auto i : mp)v.push_back(i.second);
    sort(v.begin(), v.end(), greater<int>());
    if (n > v.size())n = v.size();
    int ans = 0;
    for (int i = 0; i < n; i++)ans += v[i];
    cout << ans << endl;
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) solve();

    return 0;
}
/*   /\_/\
*   (= ._.)
*   / >  \>
*/

C:Anya and 1100

大意:

        一个01字符串,每次修改一个数,然后求1100是否在字符串中

思路:

        维护一个数组st[i],表示从i开始是否为1100,记录1100个数,每次修改的时候去掉对应4个位置的贡献,再加上修改后对应位置的贡献即可

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define  vi vector<int>
#define  vii vector<pair<int, int>>
#define ff first 
#define ss second 
// ++   ~!    */+-    <<>>    <>  ==   &^|   &&|| =

void solve()
{
    string k;cin >> k;
    int n = k.size();
    map<int, bool>st;
    int cnt = 0;
   
    k = ' ' + k;

    for (int i = 1; i <= n - 3; i++)
    {
        if (k.substr(i, 4) == "1100")
        {
            st[i] = true;
            cnt++;
        }
    }
    int q;cin >> q;
    while (q--)
    {
        int id, c;
        cin >> id >> c;
        k[id] = c + '0';
        for (int i = id; i >= id - 3 && i > 0; i--)
        {
            cnt -= st[i];
            st[i] = false;
            if (k.substr(i, 4) == "1100")
            {
                st[i] = true;
                cnt++;
            }
        }
        if (cnt)cout << "YES" << endl;
        else cout << "NO" << endl;
    }
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) solve();

    return 0;
}
/*   /\_/\
*   (= ._.)
*   / >  \>
*/

D:I Love 1543

大意:

        给一个二维数组,问从外到内每一层顺时针旋转出现1543的个数

思路:

        一个一个check,找旋转方向,看看是否为1543的开头即可,(写得有点急了,可能有更好的方法)

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define  vi vector<int>
#define  vii vector<pair<int, int>>
#define ff first 
#define ss second 
// ++   ~!    */+-    <<>>    <>  ==   &^|   &&|| =

int idx[] = { 1, 5, 4, 3 };
int n, m;
bool check(int l, int r, vector<vector<int>>& g, int pos) //后来发现lr命名为rc更好。。。将就着看把
{

    int op = idx[pos];
    if (g[l][r] == idx[pos])
    {
        if (pos == 3)return true;
        else
        {
             int num = min(min(l, r), min(n - l + 1, m - r + 1));
             int a = n - l + 1, b = m - r + 1;
             int x, y;
             if (num == l && num == r)x = l, y = r + 1; //左上
             else if (num == l && num == b)x = l + 1, y = r; //右上
             else if (num == a && num == r)x = l - 1, y = r;// 左下
             else if (num == a && num == b)x = l, y = r - 1;//右下
             else if (num == l)x = l, y = r + 1;
             else if (num == r)x = l - 1, y = r;
             else if (num == a)x = l, y = r - 1;
             else x = l + 1, y = r;
             return check(x, y, g, pos + 1);
        }
    }
    else return false;

}
void solve()
{
    cin >> n >> m;
    vector<vector<int>>g(n + 1, vi(m + 1));
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
        {
            char c;cin >> c;
            g[i][j] = c - '0';
        }
            
    int ans = 0;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
        {
            if (check(i, j, g, 0))ans++;
        }
    cout << ans << endl;
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    cin >> t;
    while (t--) solve();

    return 0;
}
/*   /\_/\
*   (= ._.)
*   / >  \>
*/

E:Reverse the Rivers

大意:

        给个二维数组,表示每个国家每个区域的水位,然后将每个区域与上一个国家的区域连通,使得水位相或,然后找一些特定区域符合要求的编号最小的国家

思路:

        刚开始还在想,这个河道连通或起来有什么用,然后看了看题暴力需要O(qmn),查询是O(1),找符合条件的是O(n),那么就至少需要把找符合条件的变成O(log),那么就需要二分找,然后想了想这怎么排序,最后看到了或操作,数越来越大,直接满足二分条件

        那么,

        (1)当要求 < 的时候,找小于这个数的最大编号的国家,每次取min

        (2)当要求>的时候,找大于这个数的最小编号的国家,每次取max

        然后我们就得到了  国家编号应小于(1)的结果,大于(2)的结果,如果两个数有交集,那么(2)的结果就是答案

代码:

#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10, INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
#define pb push_back
#define  vi vector<int>
#define  vii vector<pair<int, int>>
#define ff first 
#define ss second 
// ++   ~!    */+-    <<>>    <>  ==   &^|   &&|| =


void solve()
{
    int n, k, q;
    cin >> n >> k >> q;
    vector<vector<int>> g(n + 1, vi(k + 1));
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= k; j++)
        {
            cin >> g[i][j];
            g[i][j] |= g[i - 1][j];
        }

    while (q--)
    {
        int l = n, r = 1; // <=l ,>= r
        int a, c;

        char op;
        int m;cin >> m;
        while (m--)
        {
            cin >> a >> op >> c;

            if (op == '<')
            {
                int ll = 0, rr = n + 1;
                while (ll + 1 != rr)
                {
                    int mid = ll + rr >> 1;
                    if (g[mid][a] < c)ll = mid;
                    else rr = mid;
                }
                if (g[ll][a] >= c)ll = -1;
                l = min(ll, l);
            }
            if (op == '>')
            {
                int ll = 0, rr = n;
                while (ll + 1 != rr)
                {
                    int mid = ll + rr >> 1;
                    if (g[mid][a] > c)rr = mid;
                    else ll = mid;
                }
                if (g[rr][a] <= c)r = n + 1;
                r = max(r, rr);
            }
        }

        if (l >= r)
        {
            cout << r << endl;
        }
        else cout << -1 << endl;


    }
}

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    // cin >> t;
    while (t--) solve();

    return 0;
}
/*   /\_/\
*   (= ._.)
*   / >  \>
*/

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值