zoukankan      html  css  js  c++  java
  • Codeforces Round #644 (Div. 3) A-H 题解

    题目链接: https://codeforces.com/contest/1360

    A. Minimal Square

    题目大题: 将长宽为a, b的两个相同矩形嵌入正方形中, 问正方形的最小面积.
    解题思路: 找到长宽, 并判断两倍的宽是否大于长.

    /*
     * @Author: Hellcat
     * @Date: 2020-05-24 23:54:16
     */
    #include <bits/stdc++.h>
    using namespace std;
     
    int main() {
        int T; cin>>T;
        while(T--) {
            int a, b; cin>>a>>b;
            int Min = min(a, b);
            int Max = max(a, b);
            if(2*Min >= Max)
                cout<<pow(2*Min, 2)<<endl;
            else
                cout<<pow(Max, 2)<<endl;
        }
    }
    

    B. Honest Coach

    题目大意: 将一个数组分为A, B两组, 使得|max(A)−min(B)|最小.
    解题思路: 将数组小到大排序, 找到相邻两个元素最小的差值即为所求.

    /*
     * @Author: Hellcat
     * @Date: 2020-05-24 23:54:16
     */
    #include <bits/stdc++.h>
    using namespace std;
    int a[55];
     
    int main() {
        int T; cin>>T;
        while(T--) {
            int n; cin>>n;
            for(int i = 0; i < n; i++) cin>>a[i];
            sort(a, a + n);
            int Min = 0x3f3f3f3f;
            for(int i = 0; i < n-1; i++) {
                Min = min(Min, a[i+1] - a[i]);
            }
            cout<<Min<<endl;
        }
    }
    

    C. Similar Pairs

    题目大意: 定义奇偶性相同的一对数或满足差值为1的一对数(|x−y|=1)为Similar Pairs. 输入的数组元素个数为偶数.
    解题思路: 若输入的奇偶个数均为偶数, 则满足配对关系. 否则, 对数组排序后查找是否有满足差值为1的相邻元素. 如果有则满足题意, 否则不满足.

    /*
     * @Author: Hellcat
     * @Date: 2020-05-24 23:54:16
     */
    #include <bits/stdc++.h>
    using namespace std;
    int a[55];
     
    int main() {
        int T; cin>>T;
        while(T--) {
            int n; cin>>n;
            int e = 0, d = 0;
            for(int i = 0; i < n; i++) {
                cin>>a[i];
                if(a[i] & 1) d++;
                else e++;
            }
            if((e&1) == 0) { puts("YES"); continue; }
            sort(a, a+n);
            int diff = 0;
            for(int i = 0; i < n - 1; i++) {
                diff = a[i+1] - a[i];
                if(diff == 1) break;
            }
            if(diff == 1) { puts("YES"); continue; }
            puts("NO");
        }
    }
    

    D. Buying Shovels

    题目大意: 买n个铁锹, 只能从给定的1~k种包装中选择一种, 全部购买这种包装的商品. 求最小购买的商品数量.
    解题思路: 首先想到的是暴力枚举, 而1e9的数据量必然TLE, 随后针对暴力解法进行优化. 对特殊情况单独判定后, 结合素数判定的思路, 只要考虑前sqrt(n)的情况. 枚举2~sqrt(n)之间的数, 如果能被整除, 且满足i <= k, 则更新答案. 更新时考虑2种情况, 1)是选择包含i件商品的包裹, 购买n/i件. 2)是满足n/i <= k时选择包含n/i件商品的包裹, 购买i件. 这样一来, 时间复杂度可优化到O(logn)级别.

    /*
     * @Author: Hellcat
     * @Date: 2020-05-24 23:54:16
     * https://codeforces.com/contest/1360/problem/D
     * D. Buying Shovels
     */
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
     
    int main() {
        int T; cin>>T;
        while(T--) {
            int n, k; cin>>n>>k;
            if(k >= n) { puts("1"); continue; }
            if(k == 1) { cout<<n<<endl; continue; }
            int m = floor(sqrt(n) + 0.5);
            int res = n;
            for(int i = 2; i <= m; i++) {
                if(n%i == 0 && i <= k) { res = min(res, n/i); if(n/i <= k) res = min(res, i); }
            }
            cout<<res<<endl;
        }
    }
    

    E. Polygon

    题目大意: 训练发射炮弹, 每次只能从左侧发射到右侧或上方发射到下方, 碰到1或边界为止, 然后将所在位置由0改为1. 满足这样要求的训练输出"YES". 如图所示:

    解题思路: 首先想到dfs中的连通图思路, 从右侧及下方的1作为起点遍历. 最后如果没有剩下1则满足题意, 否则不满足. 而这题只有2个方向, 这样做显然有些复杂. 考虑不满足题意的情况, 必然存在一个1其左侧以及下方均为0. 遍历全图判断是否有这样的1即可. 同时注意, 在双重循环内一次break并不能完全跳出, 需要在双重循环外进行输出, 否则会出现输出多个"NO"的情况.

    /*
     * @Author: Hellcat
     * @Date: 2020-05-25 11:44:21
     */
    #include <bits/stdc++.h>
    using namespace std;
    char maze[55][55];
     
    int main() {
        int T; cin>>T;
        while(T--) {
            int n; cin>>n;
            for(int i = 1; i <= n; i++) cin>>maze[i]+1;
     
            bool flag = 1;
            for(int i = 1; i < n; i++)
                for(int j = 1; j < n; j++)
                    if(maze[i][j] == '1' && maze[i+1][j] == '0' && maze[i][j+1] == '0')
                        { flag = 0; break; }
            if(flag) puts("YES");
            else puts("NO");
        }
    }
    

    F. Spy-string

    题目大意: 给出n个字符串a1, a2, …, an, 如果字符串s对每个字符串都满足不相同字符不超过一个(ai[j] ≠ s[j]的个数 < 1), 输出这样的字符串s.
    解题思路: 题给数据量不大, 输入字符串个数n(1≤n≤10)和每个字符串的长度m(1≤m≤10). 字符串均由英文字符组成, 考虑暴力的解法. 由于不相同字符不超过1个, 那么将输入的第一个字符串的每个字符逐个改为'a'~'z', 再对第2~n个字符串遍历, 检查是否满足不相同字符不超过一个. 满足则输出s, 不满足输出-1.

    /*
     * @Author: Hellcat
     * @Date: 2020-05-25 14:47:14
     */
    #include <bits/stdc++.h>
    using namespace std;
     
    string s[11], res;
    int n, m;
     
    bool check() {
        for(int i = 2; i <= n; i++) {
            int cnt = 0;
            for(int j = 0; j < m; j++) {
                if(s[i][j] != res[j])
                    cnt++;
                if(cnt > 1) return 0;
            }
        }
        return 1;
    }
     
    void slove() {
        for(int i = 0; i < m; i++) {
            for(char ch = 'a'; ch <= 'z'; ch++) {
                res[i] = ch;
                if(check()) {
                    cout<<res<<endl;
                    return;
                }
                res[i] = s[1][i]; // 再改回去
            }
        }
        puts("-1");
    }
     
    int main() {
        int T; cin>>T;
        while(T--) {
            cin>>n>>m;
            for(int i = 1; i <= n; i++) cin>>s[i];
            res = s[1];
     
            slove();
        }
    }
    

    G. A/B Matrix

    题目大意: 给定一个(n×m)的矩阵, 使得每行有a个1, 每列有b个1, 其余元素均为0.
    例如n=3, m=6, a=2, b=1时, 矩阵为

    [left[ egin{matrix} 0 & 1 & 0 & 0 & 0 & 1\ 1 & 0 & 0 & 1 & 0 & 0\ 0 & 0 & 1 & 0 & 1 & 0\ end{matrix} ight] ]

    解题思路: 先考虑不满足题设的情况. 对于行, 矩阵中1的个数为(a imes n)个, 对于列则应为(b imes m)个, 当(a imes n != b imes n)时输出NO.
    其次, 将矩阵初始化为0, 考虑矩阵中如何填充1. 将题目中的样例转化为更一般的矩阵, 如:

    [left[ egin{matrix} 1 & 1 & 0 & 0 & 0 & 0\ 0 & 0 & 1 & 1 & 0 & 0\ 0 & 0 & 0 & 0 & 1 & 1\ end{matrix} ight] ]

    也是满足题设条件的输出. 对于第四个样例4 4 2 2输出的矩阵, 也可以转为

    [left[ egin{matrix} 1 & 1 & 0 & 0 \ 0 & 0 & 1 & 1 \ 1 & 1 & 0 & 0 \ 0 & 0 & 1 & 1 \ end{matrix} ight] ]

    多次尝试, 得到一般的规律后, 有如下思路: 单独考虑行, 在每行填充a个1, 用col维护填充的字符(1)的纵坐标, 根据规律只需要每次填充时++col. 同时为防止越界将col %= m即可.

    /*
     * @Author: Hellcat
     * @Date: 2020-05-26 08:55:48
     */
    #include <bits/stdc++.h>
    using namespace std;
     
    bool res[55][55];
     
    int main() {
        int T; cin>>T;
        while(T--) {
            memset(res, 0, sizeof res);
            int n, m, a, b; cin>>n>>m>>a>>b;
            if(a*n != b*m) { puts("NO"); continue; }
            int col = 0;  // column position
            for(int i = 1; i <= n; i++)
                for(int j = 1; j <= a; j++)
                    res[i][++col] = 1, col %= m;
     
            puts("YES");
            for(int i = 1; i <= n; i++) {
                for(int j = 1; j <= m; j++)
                    cout<<res[i][j];
                puts("");
            }
        }
    }
    

    H. Binary Median

    题目大意: 给定二进制字符串长度(m)((1le m le60)), 按字典序生成总共(2^m)个长度为(m)的二进制字符串. 然后从中删去n个字符串, 剩下(k=2^m-n)个字符串. 按照字典序排列后输出第(lfloor frac{k-1}{2} floor)个字符串. 例如, 当(n=3), (m=3)(a=[010, 111, 001])时, 从所有长度为3的二进制字符串中移去(a_i), 得到集合([000, 011, 100, 101, 110]), 输出中位数100.
    解题思路: 数据均为二进制数, 很容易想到使用bitset库. 集合的大小为(2^m), 若从中删除元素时间复杂度过高. 考虑使用光标移动替代集合删除元素的过程. 因此需要先求出中间位置(mid=lfloor frac{k-1}{2} floor), 如果要删除的元素(le)(mid), 那么将(mid)++, 最后得到的(mid)即中间元素十进制值, 用to_string函数转为字符串输出, 并用substr选取最右m位即可.
    由于需要对输入元素排序, 所以要用到std::bitset::to_ullong函数, 该函数的作用是将二进制数转为10进制的unsigned long long. 如图所示: 这样一来便可以用sort进行排序.

    /*
     * @Author: Hellcat
     * @Date: 2020-05-26 11:29:43
     */
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int main() {
        int T; cin>>T;
        while(T--) {
            int n, m; cin>>n>>m;
            ll a[n+10] = {0};
            ll mid = (1ll<<m)-n-1>>1;
            for(int i = 1; i <= n; i++) {
                string s; cin>>s;
                a[i] = bitset<64>(s).to_ullong();
            }
            sort(a+1, a+1+n);
            for(int i = 1; i <= n; i++)
                if(a[i] <= mid) mid++;
            cout<<bitset<64>(mid).to_string().substr(64-m)<<endl;
        }
    }
    
  • 相关阅读:
    开发模型----快速原型模型
    开发模型--瀑布模型
    python_001
    Linux文件的类型与系统目录
    流程控制语句
    test命令
    排序sort && 取消重复行uniq
    sed命令——用来对文件数据的 选取、替换、删除
    颜色RGB大全
    Markdown的使用
  • 原文地址:https://www.cnblogs.com/tedukuri/p/12961909.html
Copyright © 2011-2022 走看看