Codeforces Round #806 (Div. 4)

A.YES or YES?

题 意 : 题意:

就是判断给定的字符串是否是 y e s yes yes

思 路 : 思路:

将字符串全转为大写,判断是否和 Y E S YES YES相等

C o d e Code Code

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;
using ull = unsigned long long;

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    int _;
    for (cin >> _; _; _ --) {
        string s;
        cin >> s;

        for (auto &si : s)
            si = toupper(si);

        cout << (s == "YES" ? s : "NO") << "\n";
    }

    return 0;
}

B.ICPC Balloons

题 意 : 题意:

每个字母第一次出现时答案 + 2 +2 +2,后面再出现就 + 1 +1 +1

思 路 : 思路:

开一个数组记录出现次数,答案为出现次数大于1的字母次数+1的累计和

C o d e Code Code

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;
using ull = unsigned long long;

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    int _;
    for (cin >> _; _; _ --) {
        int n;
        cin >> n;

        string s;
        cin >> s;

        vector<int> cnt(26, 0);
        for (auto &si : s)
            cnt[si - 'A'] ++;

        int ans = 0;
        for (int i = 0; i < 26; i ++)
            if (cnt[i])
                ans += cnt[i] + 1;

        cout << ans << "\n";
    }

    return 0;
}

C.Cypher

题 意 : 题意:

给定你密码锁的最终状态,和操作次数以及每次的操作,求密码锁最初状态

思 路 : 思路:

每次操作做相反的操作就可以达到初始状态

C o d e Code Code

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;
using ull = unsigned long long;

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    int _;
    for (cin >> _; _; _ --) {
        int n;
        cin >> n;

        vector<int> a(n);
        for (int &ai : a)
            cin >> ai;

        for (int i = 0; i < n; i++) {
            int ops;
            cin >> ops;
            
            string op;
            cin >> op;
            for (auto opi : op)
                if (opi == 'D')
                    a[i] ++, a[i] %= 10;
                else
                    a[i] --, a[i] = (a[i] + 10) % 10;
        }

        for (int i = 0; i < n; i ++)
            cout << a[i] << " \n"[i == n - 1];
    }

    return 0;
}

D.Double Strings

题 意 : 题意:

n n n个字符串,判断第 i i i个字符串能否由其他字符串拼接组成,若有输出 1 1 1,否则输出 0 0 0

思 路 : 思路:

观察到每个字符串的长度不超过 8 8 8,故可使用枚举子串+ s e t set set查找,时间复杂度为 O ( n × l o g ( n ) ) O(n \times log(n)) O(n×log(n))

C o d e Code Code

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;
using ull = unsigned long long;

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    int _;
    for (cin >> _; _; _ --) {
        int n;
        cin >> n;

        set<string> ex;
        vector<string> s(n);
        for (auto &si : s) {
            cin >> si;
            ex.insert(si);
        }

        string ans = "";
        for (int i = 0; i < n; i ++) {
            bool ok = false;
            for (int j = 1; j < int(s[i].size()); j ++)
                if (ex.count(s[i].substr(0, j)) && ex.count(s[i].substr(j))) {
                    ok = true;
                    break;
                }
            ans += (ok ? '1' : '0');
        }

        cout << ans << "\n";

    }

    return 0;
}

E.Mirror Grid

题 意 : 题意:

要求整个图形是中心对称的,可以把 0 0 0变成 1 1 1也可以把 1 1 1变成 0 0 0,求最小操作次数

思 路 : 思路:

每次枚举一个正方形的一条边,然后计算 0 0 0 1 1 1的个数,若都不为 0 0 0,则将个数少的变成个数多的

C o d e Code Code

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;
using ull = unsigned long long;

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    int _;
    for (cin >> _; _; _ --) {
        int n;
        cin >> n;

        vector<string> s(n);
        for (auto &si : s)
            cin >> si;

        vector<vector<int>> vis(n, vector<int> (n));

        auto get = [&] (int x, int y) -> void {
            int ones = 0, zeros = 0;
            int dx[4] = {x, y, n-1-x, n-1-y}, dy[4] = {y, n-1-x, n-1-y, x};
            for (int i = 0; i < 4; i ++) {
                int xx = dx[i], yy = dy[i];
                if (s[xx][yy] == '1') {
                    ones ++;
                } else {
                    zeros ++;
                }
            }

            if (ones == 0 || zeros == 0)
                return ;

            int ok = int(zeros <= ones);
            for (int i = 0; i < 4; i ++)
                if (s[dx[i]][dy[i]] == '1' - ok)
                    vis[dx[i]][dy[i]] = 1;

            return ;
        };

        for (int i = 0; i < (n + 1) / 2; i ++)
            for (int j = i; j <= (n - 1) - i; j ++)
                get(i, j);

        int ans = 0;
        for (auto vi : vis)
            for (auto vij : vi)
                ans += vij;


        cout << ans << "\n";
    }

    return 0;
}

// 推导
/*

11100
11011
01011
10011
11000

11101
11111
11011
11111
11111

0,0 -> 0,n-1 -> n-1,n-1 -> n-1,0
0,1 -> 1,n-1 -> n-1,n-2 -> 1,0
0,2 -> 2,n-1 -> n-1,2 -> 2,n-1
1,1 -> 1,n-1-1 -> n-1-1,n-1-1 -> n-1-1,1

2,2 -> 2,n-1-2 -> n-1-2,n-1-2 -> n-1-2,2

*/

F.Yet Another Problem About Pairs Satisfying an Inequality

题 意 : 题意:

给一个数组 a a a,求满足 a i < i < a j < j a_{i} < i < a_{j} < j ai<i<aj<j的个数

思 路 : 思路:

在读入数据时,将 a i < i a_{i} < i ai<i的数据放进数组,然后排序,每次二分查找边界,时间复杂度 O ( n × l o g ( N ) ) O(n \times log(N)) O(n×log(N))

C o d e Code Code

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;
using ull = unsigned long long;

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    int _;
    for (cin >> _; _; _ --) {
        int n;
        cin >> n;

        vector<pair<int, int>> a;
        for (int i = 1; i <= n; i ++) {
            int x;
            cin >> x;
            if (x < i)
                a.push_back({x, i});
        }

        sort(a.begin(), a.end());
        a.push_back({1e9 + 5, 1e9 + 10});

        i64 ans = 0;
        for (int i = 0, j = 0; i < int(a.size()); i ++) {
            int l = i + 1, r = (int)a.size() - 1;
            while (l < r) {
                int mid = (l + r) >> 1;
                if (a[mid].first > a[i].second)
                    r = mid;
                else
                    l = mid + 1;
            }
            ans += (int)a.size() - r - 1;
        }

        cout << ans << "\n";
    }

    return 0;
}

G.Good Key, Bad Key

题 意 : 题意:

n n n个门,每打开一个门可以获得 a i a_{i} ai的价值,可以使用好钥匙和坏钥匙打开门,使用好钥匙要花费 k k k,使用坏钥匙会使 [ i , n ] [i,n] [i,n]后面的门内价值减少一半,求最大价值

思 路 : 思路:

考虑使用好坏钥匙的顺序,先使用好钥匙再使用坏钥匙,所获得价值为 a i + ⌊ a i + 1 / 2 ⌋ − k a_{i} + \lfloor a_{i + 1} / 2 \rfloor - k ai+ai+1/2k,先使用坏钥匙再使用好钥匙,所获得价值为 ⌊ a i / 2 ⌋ + ⌊ a i + 1 / 2 ⌋ − k \lfloor a_{i} / 2 \rfloor + \lfloor a_{i + 1} / 2 \rfloor - k ai/2+ai+1/2k,可以观察到先使用好钥匙所获得的价值一定更好,故枚举每次使用好钥匙的门,在此之前全用好钥匙,后面全用坏钥匙,坏钥匙最多可以使用31把,剩下的价值全部为0

C o d e Code Code

#include <bits/stdc++.h>

using namespace std;

using i64 = long long;
using ull = unsigned long long;

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    int _;
    for (cin >> _; _; _ --) {
        i64 n, k;
        cin >> n >> k;

        vector<i64> a(n + 1);
        for (int i = 1; i <= n; i ++) {
            cin >> a[i];
            a[i] += a[i - 1];
        }

        i64 res = 0;
        for (int i = 0; i <= n; i ++) {
            i64 sum = a[i] - k * i;
            for (int j = 1; j <= 32 && i + j <= n; j ++)
                sum += (a[j + i] - a[j + i - 1]) >> j;
            res = max(res, sum);
        }

        cout << res << "\n";

    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值