zoukankan      html  css  js  c++  java
  • Codeforces Round #632 (Div. 2)

    A. Little Artem

    题意

    有一 $n{ imes}m$ 网格,输出一种使得 与白色相邻的黑色格数 = 与黑色相邻的白色格数 $+ 1$ 的染色方案。

    思路

    一角染白。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    void solve() {
        int n, m; cin >> n >> m;
        char mp[n][m];
        fill(*mp, *mp + n * m, 'B');
        mp[0][0] = 'W';
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < m; j++) {
                cout << mp[i][j] ;
            }
            cout << "
    ";
        }
    }
    
    int main() {
        int t; cin >> t;
        while (t--) solve();
    }

    B. Kind Anton

    题意

    数组 $a$ 由 ${-1,0,1}$ 组成,可以使 $a_i$ 加上左侧 $a_j$ 任意次,问数组 $a$ $b$ 能否相等。

    思路

    判断每个与 $b_i$ 不等的 $a_i$ 左侧是否有满足条件的 $a_j$,即记录最左侧的 $-1 / 1$ 。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    void solve() {
        int n; cin >> n;
        int a[n]; for(int & i : a) cin>>i;
        int b[n]; for(int & i : b) cin>>i;
        int l_1 = find(a, a + n, -1) - a;
        int l1 = find(a, a + n, 1) - a;
        for (int i = 0; i < n; i++) {
            if ((b[i] > a[i] && l1 >= i) || (b[i] < a[i] && l_1 >= i)) {
                cout << "NO" << "
    ";
                return;
            }
        }
        cout << "YES" << "
    ";
    }
    
    int main() {
        int t; cin >> t;
        while (t--) solve();
    }

    C. Eugene and an array

    题意

    统计数组 $a$ 中有多少连续子序列,其本身及其连续子序列的和均不为 $0$ 。

    思路

    将数组从 $[0,n-1]$ 编号,若存在一和为 $0$ 的连续子序列 $[i,j]$,则 $pre\_sum[i-1] = pre\_sum[j]$,此 $0$ 序列与之前的 $i$ 个数共构成 $i+1$ 个 $0$ 序列,将之后的每个数接在 $0$ 序列的末尾也都会再构成 $i+1$ 个 $0$ 序列,若之后仍有 $0$ 序列,更新已知 $0$ 序列的最大长度后就又变成了和之前一样的情况。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    map<ll, ll> MP;
    int main() {
        int n; cin >> n;
        int a[n]; for (int & i : a) cin >> i;
        MP[0] = 0;
        ll r = -1, sum = 0, ans = (n + 1LL) * n / 2;
        for (int i = 0; i < n; i++) {
            sum += a[i];
            if (MP.count(sum)) r = max(r, MP[sum]);
            ans -= r + 1;
            MP[sum] = i + 1;
        }
        cout << ans;
    }

    D. Challenges in school №41

    题意

    输出用 $k$ 轮将字符串中所有的 $RL$ 翻转成 $LR$ 的任一方案。

    思路

    $min_k$ = 每轮翻转串中所有已存在 $RL$ 需要的轮数,$max_k$ = 每轮翻转一个 $RL$ 需要的轮数,如果 $k$ 位于二者之间则一定有解,当 $k=min_k$ 时逐轮输出即可,当 $k>min_k$ 时需要将一些轮分解输出直至 $k = min_k - used_k$ 。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    
    const int MAX_N = 3030;
    
    vector<int> v[MAX_N];
    int n, k, min_k, max_k;
    char s[MAX_N];
    
    int main() {
        cin >> n >> k >> (s + 1);
        while (1) {
            bool flag = true;
            for (int i = 1; i <= n; i++) {
                if (s[i] == 'R' && s[i + 1] == 'L') {                
                    v[min_k].push_back(i);
                    flag = false;
                }
            }
            for (int i : v[min_k]) swap(s[i], s[i + 1]);
            max_k += v[min_k].size();
            if (flag) break;
            ++min_k;
        }
        if (k < min_k || k > max_k) {
            cout << "-1";
            return 0;
        }
        for (int i = 0; i < min_k; i++) {
            while (!v[i].empty() && k > min_k - i) {
                cout << "1 " << v[i].back() << "
    ";
                v[i].pop_back();
                --k;
            }
            if (!v[i].empty()) {
                cout << v[i].size();
                for (int j : v[i]) cout << ' ' << j;
                cout << "
    ";
                --k;
            }
        }
    }

    F. Kate and imperfection

    题意

    有一集合 $S={1,2,3,...,n}$,构造大小为 $k(1<k≤n)$ 的集合,使得两两数间 $gcd$ 的最大值最小并输出该最小值。

    思路

           我们考虑如何构造两两间最大公因数的最大值最小的集合,首先肯定是把所有质数先丢进集合里,然后再把与已经在集合内的数的最大公因数 =2 的数丢进去,然后是 =3 的数……然后注意到,如果我们加入了一个合数,那么他的所有因子必定已经在集合内了,于是加入的这个数字能够产生的最大公因数就是他的最大因子,因此用埃筛维护这个贪心的过程,排序一遍输出即可。——st1vdy

    代码

    #include <bits/stdc++.h>
    using namespace std;
    int main() {
        int n; cin >> n;
        vector<int> ans(n + 1, 1);
        for (int i = 2; i <= n; i++) {
            for (int j = i + i; j <= n; j += i) {
                ans[j] = i;
            }
        }    
        sort(ans.begin(), ans.end());
        for (int i = 2; i <= n; i++) cout << ans[i] << ' ';
    }

    参考了: st1vdy 的博客。

  • 相关阅读:
    request、bs4爬虫
    1031 查验身份证
    1029 旧键盘
    1028 人口普查
    1027 打印沙漏
    1026 程序运行时间
    1025 反转链表
    1024 科学计数法
    1022 D进制的A+B
    1021 个位数统计
  • 原文地址:https://www.cnblogs.com/Kanoon/p/12664168.html
Copyright © 2011-2022 走看看