Codeforces Round #644 (Div. 3)

Codeforces Round #644 (Div. 3)

A. Minimal Square

题意: t个测试样例,每次给定a和b,表示一个矩形的长和宽,让你找到一个最小的正方形能够容纳2个矩形。

题解: 分类讨论。直接分类讨论,具体见代码:

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
int const MAXN = 2e5 + 10;
int n, m, T;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> T;
    while(T--) {
        cin >> n >> m;
        if (n < m) swap(n, m);
        if (n % m == 0 && n / m >= 2) cout << n * n << endl;
        else if (m * 2 < n) cout << n * n << endl;
        else {
            int ori = m;
            while(m <= n) m += ori;
            cout << m * m << endl;
        }
    }
    return 0;
}

B. Honest Coach

题意: 给定n个数字,让你将n个数字分为2组,使得第一组的最小值减去第二组的最大值最小。计算这个差值是多少

题解: 思维。这个差值就是排序完之后2个相邻数字的最小差值

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
int const MAXN = 2e5 + 10;
int n, m, T, a[MAXN];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> T;
    while(T--) {
        cin >> n;
        int res = 1001;
        for (int i = 1; i <= n; ++i) cin >> a[i];
        sort(a + 1, a + 1 + n);
        for (int i = 2; i <= n; ++i) {
            res = min(res, a[i] - a[i - 1]);
        }
        cout << res << endl;
    }
    return 0;
}

C. Similar Pairs

题意: 给定n个数字,将n个数字分为若干对,使得每对数字要不然奇偶性不同,要不然相邻,问是否能够划分

题解: 思维。如果n个数字不是偶数,那么一定无法分割。如果偶数个数和奇数个数不相同时,如果相邻的组数大于等于1,那么就能够成功划分。

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
int const MAXN = 100;
int n, m, T;
int a[MAXN], cnt = 0, cnt1, cnt2;
unordered_map<int, int> st;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> T;
    while(T--) {
        cnt1 = cnt2 = cnt = 0;
        st.clear();
        cin >> n;
        for (int i = 1; i <= n; ++i) cin >> a[i];
        sort(a + 1, a + 1 + n);
        for (int i = 1; i <= n; ++i) {
            if (a[i] & 1) cnt1++;
            else cnt2++;
            if (st.count(a[i] - 1)) cnt++, st.erase(a[i] - 1);
            else st[a[i]] = 1;
        }
        // cout << cnt1 << " " << cnt2 << " " << cnt << endl;
        int flg = 1;
        if (n % 2 != 0) flg = 0;
        if (cnt1 % 2 != 0) {
            if (!cnt) flg = 0;
        }
        if (flg) cout << "YES\n";
        else cout << "NO\n";
    }
    return 0;
}

D. Buying Shovels

题意: 给定n和k,要求找到小于k的因子x,使得n / x最小,打印这个值。

题解: 数学。枚举n的所有因子,然后不断更新答案即可

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
int const INF = 1e9 + 7;
int n, m, T;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> T;
    while(T--) {
        cin >> n >> m;
        if (n <= m) {
            cout << 1 << endl;
            continue;
        }
        int res = INF;
        for (int i = 2; i <= n /i; ++i) {  // 枚举到sqrtx(x)
            if (n % i == 0) {  // 如果能够整除
                if (i <= m) res = min(res, n / i);
                if (n / i <= m) res = min(res, i);
            }
        }
        res = min(res, n);
        cout << res << endl;
    }
    return 0;
}

E. Polygon

题意: 给定一个n * n 的网格,下标从1开始,初始时每个数字都填为0。现在在第0行和第0列有大炮,大炮每次能够发射权值为1的炮弹。大炮能够打的尽可能远,知道碰到1。现在给定一个01矩阵,问这个矩阵是否为合法序列

题解: 思维。只要判断每个1是否右侧或者下侧存在1即可

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
int const MAXN = 2e5 + 10;
int n, m, T;
char mp[60][60];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> T;
    while(T--) {
        cin >> n;
        for (int i = 0; i < n; ++i) cin >> mp[i];
        int flg = 1;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (mp[i][j] == '1') {
                    if (i + 1 < n && j + 1 < n && mp[i + 1][j] == '0' && mp[i][j + 1] == '0')  flg = 0;
                    // if (!flg) cout << i << " " << j << endl;
                }
            }
        }
        if (flg) cout << "YES\n";
        else cout << "NO\n";
    }
    return 0;
}

F. Spy-string

题意: 给定n个长度为m的字符串,要求找到一个字符串s,使得s和n个字符串中的任意1个字符串最多只会有1个字符不相同。打印这个字符串s

题解: 暴力枚举。可以看到数字的规模特别小,那么我们直接拿第一个字符串的每一个位置进行枚举,枚举每一个位置,将其替换为任意一个字符,然后判断一下替换完的字符串是否满足题意即可

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
int n, m, T;
string s[15];

int check(string tmp) {
    for (int i = 1; i <= n; ++i) {
        int cnt = 0;
        for (int j = 0; j < m; ++j) cnt += (s[i][j] != tmp[j]);
        if (cnt > 1) return 0;
    }
    return 1;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> T;
    while(T--) {
        cin >> n >> m;
        for (int i = 1; i <= n; ++i) cin >> s[i];
        string ss = s[1];
        int flg = 0;
        for (int i = 0; i < m; ++i) {
            for (char op = 'a'; op <= 'z'; op++) {
                string tmp = ss;
                tmp[i] = op;
                if (check(tmp)) {
                    flg = 1;
                    cout << tmp << endl;
                    break;
                }
            }
            if (flg) break;
        }
        if (!flg) cout << -1 << endl;
    }
    return 0;
}

G. A/B Matrix

题意: 给定n、m、a、b,要求构造一个n * m 的网格,使得每一行恰好有a个1,每一列恰好有b个1。

题解: 构造。对于每一个1,它属于一行,也属于一列。因此,满足条件的矩阵条件为:n * a == m * b。

对于构造,交叉构造,具体见代码

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
int const MAXN = 50 + 10;
int n, m, T, a, b;
int g[MAXN][MAXN];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> T;
    while(T--) {
        cin >> n >> m >> a >> b;
        if (n * a != m * b) {
            cout << "NO\n";
            continue;
        }
        cout << "YES\n";
        memset(g, 0, sizeof g);
        int x = 0;
        for(int i = 0;i < n;i++)
            for(int j = 0;j < a;j++)
                {g[i][x++] = 1;x %= m;}//交错赋值,本来可以arr[i][(++x)%m] = 1的,x的初值为-1,但是感觉花里胡哨了就没写。。
        for(int i = 0;i < n;i++)
            for(int j = 0;j < m;j++)
                j != m-1 ? cout << g[i][j] : cout << g[i][j] << endl;
        } 
    return 0;
}

H. Binary Median

题意: 现在有一个集合,集合内的元素为所有长度为m的字符串,现在从这个集合内删除n个字符串si,给定n、m和删除的n个字符串,要求集合内的字符串的中位数是哪一个。

题解: 思维 + 贪心。对于每一个二进制数字都可以对应到一个十进制数字,那么我求二进制数字的中位数和求十进制数字的中位数等价。删除完n个字符串后,集合内的字符串数目为(1 << m) - n,因此中位数就要求,前面要有k = ((1 << m) - n) / 2个数字。因此,每次删除前k个数字内的数字,那么我k指针就要向右移,以保证k指针左边的数字足够。

代码:

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;
int const MAXN = 2e5 + 10;
int n, m, T;
LL a[110];
int res[70];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> T;
    while(T--) {
        cin >> n >> m;
        memset(a, 0, sizeof a);
        for (int i = 1; i <= n; ++i) {
            string s;
            cin >> s;
            for (int j = 0; j < m; ++j) a[i] = a[i] * 2 + s[j] - '0';
        }

        sort(a + 1, a + 1 + n);
        LL k = (((1ll << m) - n) - 1) / 2;
        for (int i = 1; i <= n; ++i) 
            if (a[i] <= k) k++;
        for (int i = 0; i < m; ++i) res[i] = k % 2, k /= 2;
        for (int i = m - 1; i >= 0; --i) cout << res[i];
        cout << endl;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值