zoukankan      html  css  js  c++  java
  • Codeforces #640 div4 A

    A. Sum of Round Numbers

    (Description:)

      给你一个数 (n),将其拆分为几个数的和,这几个数满足除最高位外,其余位全为 (0)

    (Solve:)

      我直接以字符串读入,然后扫描一遍记下答案即可。

    (Code:)

    #include <bits/stdc++.h>
    using namespace std;
    
    int main(){
        int t; cin >> t;
        while(t --){
            char num[10];
            scanf("%s", num + 1);
            vector<string> ans;
            int len = strlen(num + 1);
            for(int i = 1; i <= len; i ++){
                if(num[i] == '0') continue; // 是 0 就跳过
                string tmp = "";
                tmp += num[i];
                for(int j = 1; j <= len - i; j ++) tmp += '0'; // 加 0
                ans.push_back(tmp);
            }
            cout << ans.size() << endl;
            for(int i = 0; i < ans.size(); i ++) cout << ans[i] << " ";
            puts("");
        }
        return 0;
    }
    

    (\)

    B. Same Parity Summands

    (Description:)

      给你 (n, k) 两个数,问是否存在数组 (a) 满足 (n = a_1 + a_2 + a_3 +...+a_k)(a) 里的数要么都是奇数,要么都是偶数。

    (Solve:)

      根据 (n, k) 的奇偶性来分类讨论即可。

    (Code:)

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 110;
    
    int a[N];
    
    int main(){
        int t; cin >> t;
        while(t --){
            int n, k; cin >> n >> k;
            
            if(n & 1){ 
                if(k & 1){ 
                    if(n < k) { puts("NO"); continue; } // 即使全为 1 都大于 n
                    for(int i = 1; i < k; i ++) a[i] = 1;
                    a[k] = n - k + 1;
                }else{ // k 是偶数不合法
                    puts("NO"); continue;
                }
            }else{
                if(k & 1){
                    if(n / 2 < k) { puts("NO"); continue; } // 是偶数每一项至少为 2
                    for(int i = 1; i < k; i ++) a[i] = 2;
                    a[k] = n - (k - 1) * 2;
                }else{
                    // 这种情况下,每个数为奇数更优
                    if(n < k) { puts("NO"); continue; }
                    for(int i = 1; i < k; i ++) a[i] = 1;
                    a[k] = n - k + 1;
                }
            }
            puts("YES");
            for(int i = 1; i <= k; i ++) printf("%d ", a[i]);
            puts("");
        }
        return 0;
    }
    

    (\)

    C. K-th Not Divisible by n

    (Description:)

      给出 (n, k),输出不能被 (n) 整除的第 (k) 个数。

    (Solve:)

      对于每 (n) 个数,都有 (n - 1) 个数不能被 (n) 整除,那么根据这个我们可以轻易算出第 (k) 个数。

    (Code:)

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int main(){
        int t; cin >> t;
        while(t --){
            ll n, k; cin >> n >> k;
            ll t = k / (n - 1);
            ll c = k - t * (n - 1);
            long long ans = t * n + (c > 0 ? c : -1); // c = 0 就必须 -1
            cout << ans << endl;
        }
        return 0;
    }
    

    (\)

    D. Alice, Bob and Candies

    (Description:)

      两个人轮流吃数组中的元素,一个从左往右,一个从右往左,第一次只吃 (a[i]),每次吃掉的元素和要严格大于上一个人吃的,求吃了几次和每个人吃了多少?

    (Solve:)

      直接按照题意模拟即可。

    (Code:)

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e3 + 10;
    
    int arr[N];
    
    int main(){
        int t; cin >> t;
        while(t --){
            int n; cin >> n;
            for(int i = 1; i <= n; i ++) scanf("%d", &arr[i]);
            int l = 1, r = n, a = 0, b = 0;
            int prev_a = 0, prev_b = 0; // 上次吃的总和
            int i; // 移动次数
            for(i = 1; ; i ++){
                if(i & 1){
                    while(l <= r){
                        a += arr[l];
                        prev_a += arr[l ++];
                        if(prev_a > prev_b){
                            prev_b = 0;
                            break;
                        }
                    }
                }else{
                    while(l <= r){
                        b += arr[r];
                        prev_b += arr[r --];
                        if(prev_b > prev_a){
                            prev_a = 0;
                            break;
                        }
                    }
                }
                if(l > r) break;
            }
            printf("%d %d %d
    ", i, a, b);
        }
        return 0;
    }
    

    (\)

    E. Special Elements

    (Description:)

      长度为 (n) 的数组 (a),存在多少 (a_i = a_l + a_{l+1} + ... + a_r(1leq l < rleq n,a_i leq n)) ? 相同元素也要记入答案中。

    (Solve:)

      预处理出前缀和数组,然后来枚举区间 ([l, r]) ,记录答案即可。

    (Code:)

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e4;
    
    int a[N], sum[N], m[N];
    
    int main(){
        int t; cin >> t;
        while(t --){
            memset(m, 0, sizeof m); 
            int n; cin >> n;
            sum[0] = 0;
            for(int i = 1; i <= n; i ++){
                scanf("%d", &a[i]);
                m[a[i]] ++; // 记录每个数出现的次数
                sum[i] = sum[i - 1] + a[i]; // 前缀和
            }
            int ans = 0;
            for(int l = 1; l <= n; l ++)
                for(int r = l + 1; r <= n; r ++){
                    int t = sum[r] - sum[l - 1];
                    if(t > n) continue; // 每个数都是 <= n,> n 显然不合法
                    ans += m[t];
                    m[t] = 0; // 加了必须清空
                }
            cout << ans << endl;
        }
        return 0;
    }
    

    (\)

    F. Binary String Reconstruction

    (Description:)

      对于一个二进制字符串 (s),给出 (n_0, n_1, n_2),分别代表在 (n - 1) 对相邻字符组里面全是 (0),有 (1)(0),全是 (1) 的个数。输出满足一个这样条件的 (s)

    (Solve:)

      显然 (len[s] = n_0 + n_1 + n_2 + 1)。直接暴力构造即可。左边为全 (0),中间为 (0, 1),右边为 (1) 即可。注意要判断一下 (n_1) 的奇偶性。

    (Code:)

    #include <bits/stdc++.h>
    using namespace std;
    
    int main(){
        int t; cin >> t;
        while(t --){
            int n0, n1, n2; cin >> n0 >> n1 >> n2;
            string s = "";
            if(n1 == 0){ // 特判
                for(int i = 1; i <= n0; i ++) s += '0';
                for(int i = 1; i <= n2; i ++) s += '1';
                s += n0 ? '0' : '1';
                cout << s << endl;
                continue;
            }
            for(int i = 1; i <= n0; i ++) s += '0';
            if(n1 & 1){
                for(int i = 1; i <= (n1 + 1) / 2; i ++){
                    s += '0'; s += '1';
                }
            }else{
                for(int i = 1; i <= n1 / 2; i ++){
                    s += '0'; s += '1';
                }
            }
            for(int i = 1; i <= n2; i ++) s += '1';
    
            if((n1 & 1) == 0) {
                s += '0';
            }
            cout << s << endl;
        }
        return 0;
    }
    

    (\)

    G. Special Permutation

    (Description:)

      是否存在一种 ([1, n]) 的 排列使得相邻两个数差值的绝对值在 ([2, 4]) 之间?

    (Solve:)

      显然 (n < 4) 是无解的。

      所以我的想法是在 (n = 4) 基础上推出其他的。

    [n = 4: (3, 1, 4, 2)\n = 5: (3, 1, 4, 2, 5)\n = 6: (3, 1, 4, 6, 2, 5)\n = 7: (3, 1, 4, 6, 2, 5, 7)\n = 8: (3, 1, 4, 8, 6, 2, 5, 7) ]

      如果 (n) 是奇数,就加在上一项的后面;如果 (n) 是偶数,就在中间找一个可以插入的地方,是一定存在的。

      理由,奇数显然是一定可以的,对于偶数的情况下,我们可以发现,对于 (n = 6) 的情况,是插入在 ((4, 2)) 之间的,那么就会存在 ((4, 6)),那么对于 (n = 8) 的情况就可以插入在 ((4, 6)) 之间,对于 (n = 10) 的情况就可以插入在 ((6, 8)) 之间,依次类推,对于 (n) (偶数)来说,可以插入在 ((n - 4, n - 2)) 之间,所以是一定有解的。

    (Code:)

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e3 + 10;
    
    vector<int> vec[N]; // vec[i] 代表 n = i 时的合法排列
    
    // 预处理
    void init(){
        vec[4] = {3, 1, 4, 2};
        for(int i = 5; i < N; i ++){
            if(i & 1){ // 奇数直接加在上一项后面
                vec[i] = vec[i - 1];
                vec[i].push_back(i);
            }else{
                int mark = 0; // 标记是否加了 i
                for(int j = 0; j < vec[i - 1].size(); j ++){
                    int num = vec[i - 1][j];
                    vec[i].push_back(num);
                    // 判断 vec[i - 1][j], i, vec[i - 1][j + 1] 这样是否合法,合法就插入
                    if(!mark && abs(i - num) >= 2 && abs(i - num) <= 4 && j < i - 2 && abs(i - vec[i-1][j+1]) >= 2 && abs(i - vec[i-1][j + 1]) <= 4){
                        vec[i].push_back(i);
                        mark = 1;
                    }
                }
            }
        }
    }
    
    int main(){
        init();
        int t; cin >> t;
        while(t --){
            int n; cin >> n;
            if(n <= 3) { puts("-1"); continue; }
            for(int i = 0; i < n; i ++) cout << vec[n][i] << " ";
            puts("");
        }
        return 0;
    }
    
  • 相关阅读:
    Javascript异步编程的4种方法
    同步编程和异步编程
    关于js 异步回调的一些方法
    array的方法 没记住的
    阮一峰关于reduce 和transduce的博客
    CSS开发小技巧
    提升自己的一个网址
    asm.js 和 Emscripten 入门教程
    Koa -- 基于 Node.js 平台的下一代 web 开发框架
    C#中使用handsonetable的一个例子
  • 原文地址:https://www.cnblogs.com/nonameless/p/12867717.html
Copyright © 2011-2022 走看看