Codeforces Round #644 (Div. 3) A - H 解题报告

题目链接


\(A. Minimal Square\)

\(Description:\)

​   将两个相同得矩形放在一个正方形中,求正方形的最小面积。

\(Solution:\)

  取得矩形的长和宽,显然只有两个矩形横着放最优。

\(Code:\)

/*
@Author: nonameless
@Date:   2020-05-25 08:29:45
@Email:  2835391726@qq.com
@Blog:   https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI  = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF  = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll  gcd(ll  a, ll  b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }


int main(){

    int t; cin >> t;
    while(t --){
        int a, b; cin >> a >> b;
        if(a < b) swap(a, b);
        int e = max(a, b + b);
        cout << e * e << endl;
    }
    return 0;
}


\(B. Honest Coach\)

\(Description:\)

  将 \(n\) 个数分为两组,要求一组的最大值减去另一组的最小值的绝对值最小。

\(Solution:\)

  排序后,在相邻两个数之间取差。

\(Code:\)

/*
@Author: nonameless
@Date:   2020-05-25 08:38:29
@Email:  2835391726@qq.com
@Blog:   https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI  = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF  = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll  gcd(ll  a, ll  b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }


const int N = 55;

int s[N];

int main(){

    int t; cin >> t;
    while(t --){
        int n; cin >> n;
        for(int i = 1; i <= n; i ++) scanf("%d", &s[i]);
        sort(s + 1, s + n + 1);
        int ans = INF;
        for(int i = 2; i <= n; i ++) ans = min(ans, s[i] - s[i - 1]);
        cout << ans << endl;
    }
    return 0;
}


\(C. Similar Pairs\)

\(Description:\)

  给出 \(n\) 个数,要求两个进行配对,要求是 \(a_i,\ a_j\) 同奇偶或者 \(|a_i - a_j| = 1\)。问这 \(n\) 个数能否完成配对?

\(Solution:\)

  由于 \(n\) 是偶数,那么当数列中奇数的个数为偶数时,偶数的个数也为偶数,显然这种情况下是一定可以的,那么当数列中奇数的个数为奇数时,我们只需要找到一组 \(|a_i - a_j| = 1\) 即可,由于 \(a_i,\ a_j\) 一定是一个是奇数,一个是偶数的,那么减去这一组之后,奇数的个数和偶数的个数都变为了偶数,回到了第一中情况。

\(Code:\)

/*
@Author: nonameless
@Date:   2020-05-25 08:42:55
@Email:  2835391726@qq.com
@Blog:   https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI  = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF  = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll  gcd(ll  a, ll  b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }

const int N = 55;

int a[N];

int main(){

    int t; cin >> t;
    while(t --){
        int n; cin >> n;
        for(int i = 1; i <= n; i ++) scanf("%d", &a[i]);
        sort(a + 1, a + n + 1);
        int mark = 0;
        int cntOdd = 0;
        for(int i = 1; i <= n; i ++){
            if(a[i] & 1) cntOdd ++;
            if(i < n && a[i] + 1 == a[i + 1]) mark = 1;
        }
        if(mark || cntOdd % 2 == 0) puts("YES");
        else puts("NO");
    }
    return 0;
}


\(D. Buying Shovels\)

\(Description:\)

  给你 \(n\)\(k\),要求在 \([1, k]\) 中找到一个数 \(x\),使得 \(n\ mod\ x = 0\),并且 \(\frac{n}{x}\) 最小。

\(Solution:\)

  找到 \([1, k]\)\(n\) 最大的约数即可。

\(Code:\)

/*
@Author: nonameless
@Date:   2020-05-25 09:03:23
@Email:  2835391726@qq.com
@Blog:   https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI  = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF  = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll  gcd(ll  a, ll  b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }


int cal(int n, int k){
    int res = 1;
    for(int i = 2; i * i <= n; i ++){
        if(n % i == 0){
            if(i <= k) res = max(res, i);
            if(n / i <= k) res = max(res, n / i);            
        }
    }
    return res;
}

int main(){

    int t; cin >> t;
    while(t --){
        int n, k; cin >> n >> k;
        if(k >= n) puts("1");
        else{
            int ans = cal(n, k);
            cout << n / ans << endl;
        }
    }
    return 0;
}


\(E. Polygon\)

\(Description:\)

  矩阵的最上边和最左边有一排大炮,可以无限制的打出一个 \(1\)\(1\) 遇到 \(1\) 或矩阵的边界就停下,并且他停下的那一格变为了 \(1\),具体可以看原题的图.给出打完后的矩阵,问是否是合法的?

\(Solution:\)

  我们直接去暴力,看每一个 \(1\) 的右边和下边一格是否是 \(1\) 或边界,有一个不满足就是不合法的。

\(Code:\)

/*
@Author: nonameless
@Date:   2020-05-25 09:22:27
@Email:  2835391726@qq.com
@Blog:   https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI  = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF  = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll  gcd(ll  a, ll  b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }

const int N = 55;

char s[N][N];

int main(){

    int t; cin >> t;
    while(t --){
        int n; cin >> n;
        for(int i = 1; i <= n; i ++) scanf("%s", s[i] + 1);
        int mark = 1;
        for(int i = 1; i <= n; i ++){
            for(int j = 1; j <= n; j ++){
                if(s[i][j] == '1'){
                    if(i != n && j != n && s[i + 1][j] == '0' && s[i][j + 1] == '0'){
                        mark = 0;
                        break;
                    }
                }
            }
            if(mark == 0) break;
        }

        if(mark) puts("YES");
        else puts("NO");
            
    }
    return 0;
}


\(F. Spy-string\)

\(Description:\)

  给出 \(n\) 个字符串,问是否存在一个基串去与这 \(n\) 个字符串比较,最多只有一个位置的字符不一样?

\(Solution:\)

  还是暴力,我们直接以第一个字符串为基串,然后去改变他每个位置上的字符(每次只能改变一个位置),来和其他的比较,看是否合法。

\(Code:\)

/*
@Author: nonameless
@Date:   2020-05-25 09:32:49
@Email:  2835391726@qq.com
@Blog:   https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI  = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF  = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll  gcd(ll  a, ll  b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }

const int N = 15;

int n, m;
char s[N][N];

int chk(char *t){
    for(int i = 2; i <= n; i ++){
        int cnt = 0;
        for(int j = 1; j <= m; j ++){
            if(s[i][j] != t[j]) cnt ++;
        }
        if(cnt > 1) return 0;
    }
    return 1;
}

int main(){

        int t; cin >> t;
        while(t --){
            cin >> n >> m;
            for(int i = 1; i <= n; i ++) scanf("%s", s[i] + 1);
            char t[N];
            for(int i = 1; i <= m; i ++) t[i] = s[1][i];
            int flag = 0;
            for(int i = 1; i <= m; i ++){
                for(char j = 'a'; j <= 'z'; j ++){
                    t[i] = j;
                    if(chk(t)){
                        flag = 1;
                        break;
                    }
                }
                if(flag) break;
                t[i] = s[1][i];
            }

            t[m + 1] = '\0';
            if(flag) printf("%s\n", t + 1);
            else puts("-1");
                
        }
    return 0;
}


\(G. A/B Matrix\)

\(Description:\)

  问是否存在一个 \(n \times m\) 的矩阵,使得每一行有 \(a\)\(1\),每一列有 \(b\)\(1\)

\(Solution:\)

  先根据行来构造,但每一行应该怎么放呢?为了尽可能的合理,每一列我们都应该照顾到,所以我们顺序的摆放过去。

\(Code:\)

/*
@Author: nonameless
@Date:   2020-05-25 16:57:59
@Email:  2835391726@qq.com
@Blog:   https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI  = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF  = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll  gcd(ll  a, ll  b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }

const int N = 55;

int n, m, a, b;
int mt[N][N];

int chk(){ // 判断构造完是否合法
    for(int j = 0; j < m; j ++){
        int cnt = 0;
        for(int i = 0; i < n; i ++)
            cnt += mt[i][j];
        if(cnt != b) return 0;
    }
    return 1;
}

int main(){

    int t; cin >> t;
    while(t--){
        cin >> n >> m >> a >> b;
        memset(mt, 0, sizeof mt);
        int idx = 0; // 从 0 开始
        for(int i = 0; i < n; i ++){
            for(int j = idx; j < idx + a; j ++){ // 顺序构造,注意模 m
                mt[i][j % m] = 1;
            }
            idx += a;
        }

        if(!chk()) puts("NO");
        else{
            puts("YES");
            for(int i = 0; i < n; i ++){
                for(int j = 0; j < m; j ++)
                    printf("%d", mt[i][j]);
                puts("");
            }
        }
    }
    return 0;
}


\(H. Binary Median\)

\(Description:\)

  有 \(2^m\) 个长度为 \(m\)\(01\) 字符串,在去掉 \(n\) 个字符串后,对剩余的字符串排序,问下标为中位数的那个字符串是什么?

\(Solution:\)

  参考博文

  先把字符串转为十进制,然后我们不要一下删除掉 \(n\) 个数,而是一个一个的删掉,对于删去一个数之后,中位数就有可能发生变化,在手动模拟几遍之后就可以发现规律:

  当前数的个数为偶数,如果要删去的数要 \(\leq\) 中位数,那么中位数向右移一位;

  当前数的个数为奇数,如果要删去的数要 \(\geq\) 中位数,那么中位数向左移一位。

\(Code:\)

/*
@Author: nonameless
@Date:   2020-05-25 20:58:38
@Email:  2835391726@qq.com
@Blog:   https://www.cnblogs.com/nonameless/
*/
#include <bits/stdc++.h>
#define x first
#define y second
#define all(x) x.begin(), x.end()
#define sz(x) (int)x.size()
#define pb push_back
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
const double PI  = acos(-1.0);
const double eps = 1e-8;
const int INF = 0x3f3f3f3f;
const ll LNF  = 0x3f3f3f3f3f3f;
inline int gcd(int a, int b) { return b ? gcd(b, a % b) : a; }
inline ll  gcd(ll  a, ll  b) { return b ? gcd(b, a % b) : a; }
inline int lcm(int a, int b) { return a * b / gcd(a, b); }


int main(){

    int t; cin >> t;
    while(t --){
        int n, m;
        cin >> n >> m;
        map<ll, int> mp;
        vector<ll> vec;
        for(int i = 1; i <= n; i ++){
            string s; cin >> s;
            ll t = 0;
            for(int j = 0; j < m; j ++) t = t * 2 + s[j] - '0';
            //cout << "t = " << t << endl;
            vec.pb(t);
        }

        ll k = 1ll << m;
        ll ans = (k - 1) / 2;  
        for(int i = 0; i < n; i ++){
            mp[vec[i]] = 1;
            if(k % 2 == 0){
                if(vec[i] <= ans){
                    ans ++;
                    while(mp[ans]) ans ++;
                }
            }else{
                if(vec[i] >= ans){
                    ans --;
                    while(mp[ans]) ans --;
                }
            }
            k --; // 由于删去了一个数,所以个数 -1
          //  cout << "ans = " << ans << endl;
        }

        string s = "";
        for(int i = 0; i < m; i ++){
            if(ans >> i & 1) s += '1';
            else s += '0';
        }
        reverse(all(s));
        cout << s << endl;
    }

    return 0;
}


posted @ 2020-05-25 22:11  nonameless  阅读(159)  评论(1编辑  收藏  举报