Codeforces Round #956 (Div. 2) and ByteRace 2024

被这场比赛整自闭 了;

首先看A题

如果一个整数数组 a1,a2,⋯,an𝑎1,𝑎2,⋯,𝑎𝑛 满足以下条件,那么这个数组就是受整数 k𝑘 约束的美丽数组:

  • 所有 j𝑗 上的 aj𝑎𝑗 之和,其中 j𝑗 是 k𝑘 的倍数, 1≤j≤n1≤𝑗≤𝑛 是 k𝑘 的倍数。本身是 k𝑘 的倍数。
  • 更正式地说,如果 ∑k|jaj∑𝑘|𝑗𝑎𝑗 能被所有 1≤j≤n1≤𝑗≤𝑛 的 k𝑘 整除,那么数组 a𝑎 在 k𝑘 的约束下是美丽的。这里, k|j𝑘|𝑗 表示 k𝑘 除以 j𝑗 ,即 j𝑗 是 k𝑘 的倍数。

给定 n𝑛 ,求一个正非零整数数组,其中每个元素都小于或等于 105105 ,且所有 1≤k≤n1≤𝑘≤𝑛 都是美丽的。

可以证明答案总是存在的。

这个题其实思路很明显

就是输出1到n就行

然后是B题

给你两个由数字 a𝑎 和 b𝑏 组成的网格,网格中有 n𝑛 行和 m𝑚 列。网格中的所有数值都是 00 、 11 或 22 。

您可以多次对 a𝑎 执行以下操作:

  • 选取网格中任意一个长宽为 ≥2≥2 的子矩形。您可以选择整个网格作为子矩形。
  • 子矩形有四个角。取所选子矩形中任意一对斜对角,并将它们的值加上 11 ,模为 33 。
  • 对于未选中的一对角,在它们的值上加上 22 modulo 33 。

需要注意的是,此操作只改变被选中的子矩形的角的值。

是否可以通过任意次数(可能为零)的上述操作将网格 a𝑎 转换为网格 b𝑏 ?

这种题一般都是找规律,不涉及什么算法知识

由于对角上分别加1与2,这就可以看为2X2的矩阵,然后会发现他的行与列mod3的值其实是不变的,我们可以去对应他所要变得的矩阵

 int n, m; cin >> n >> m;
    int flag = 1;
    memset(p, 0, sizeof(p)); // 初始化 p 数组
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++) {
            cin >> a[i][j];
            p[i] += (a[i][j]-'0');
        }
    for (int i = 1; i <= n; i++)
    {
        int sum = 0;
        for (int j = 1; j <= m; j++) {
            cin >> b[i][j];
            sum += (b[i][j] - '0');
        }
        if (sum % 3 != p[i] % 3)flag = 0;
    }
    int fale = 1;
    for (int i = 1; i <= m; i++)
    {
        int sum1 = 0; int sum2 = 0;
        for (int j = 1; j <= n; j++)
        {
            sum1 += a[j][i];
            sum2 += b[j][i];
        }
        if (sum1 % 3 != sum2 % 3)fale = 0;
    }
    if (flag&&fale)cout << "YES\n";
    else cout << "NO\n";
   
   

还有一种写法,就是挨个来遍历,暴力做法,然后判断最后的行和列是否对应

void readGrid(vector<vector<int>>& grid, int n, int m) {
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            char c;
            cin >> c;
            grid[i][j] = c - '0';
        }
    }
}
bool canTransform(vector<vector<int>>& a, vector<vector<int>>& b, int n, int m) {
    for (int i = 0; i < n - 1; ++i) {
        for (int j = 0; j < m - 1; ++j) {
            while (a[i][j] != b[i][j]) {
                int diff = (b[i][j] - a[i][j] + 3) % 3;
                a[i][j] = (a[i][j] + diff) % 3;
                a[i][j + 1] = (a[i][j + 1] + 2 * diff) % 3;
                a[i + 1][j] = (a[i + 1][j] + 2 * diff) % 3;
                a[i + 1][j + 1] = (a[i + 1][j + 1] + diff) % 3;
            }
        }
    }
 
    // Check the last row and column
    for (int i = 0; i < n; ++i) {
        if (a[i][m - 1] != b[i][m - 1]) {
            return false;
        }
    }
 
    for (int j = 0; j < m; ++j) {
        if (a[n - 1][j] != b[n - 1][j]) {
            return false;
        }
    }
 
    return true;
}
 
int main() {
    int t;
    cin >> t;
    while (t--) {
        int n, m;
        cin >> n >> m;
        vector<vector<int>> a(n, vector<int>(m));
        vector<vector<int>> b(n, vector<int>(m));
 
        // Read grids a and b
        readGrid(a, n, m);
        readGrid(b, n, m);
 
        // Check if we can transform a to b
        if (canTransform(a, b, n, m)) {
            cout << "YES" << endl;
        }
        else {
            cout << "NO" << endl;
        }
    }
    return 0;
}

 然后我们看c题,这道题真给我整自闭了

爱丽丝、鲍勃和查理想分享一个切成 n𝑛 块的长方形蛋糕。每个人认为每块蛋糕的价值都不同。爱丽丝认为 i𝑖 /th块的价值是 ai𝑎𝑖 ,鲍勃认为是 bi𝑏𝑖 ,而查理认为是 ci𝑐𝑖 。

所有 ai𝑎𝑖 、所有 bi𝑏𝑖 和所有 ci𝑐𝑖 的总和是一样的,都等于 tot𝑡𝑜𝑡 。

考虑到每个人的每块蛋糕的值,你需要给每个人一块连续的蛋糕。换句话说,对于 Alice、Bob 和 Charlie 来说,这些子数组左端和右端的索引(给每个人的蛋糕片)可以分别表示为 (la,ra)(𝑙𝑎,𝑟𝑎) 、 (lb,rb)(𝑙𝑏,𝑟𝑏) 和 (lc,rc)(𝑙𝑐,𝑟𝑐) 。分割需要满足以下约束条件:

  • 没有一个棋子被分配给多人,即 [la,…,ra][𝑙𝑎,…,𝑟𝑎] 、 [lb,…,rb][𝑙𝑏,…,𝑟𝑏] 和 [lc,…,rc][𝑙𝑐,…,𝑟𝑐] 中没有两个子数组相交。
  • ∑rai=laai,∑rbi=lbbi,∑rci=lcci≥⌈tot3⌉∑𝑖=𝑙𝑎𝑟𝑎𝑎𝑖,∑𝑖=𝑙𝑏𝑟𝑏𝑏𝑖,∑𝑖=𝑙𝑐𝑟𝑐𝑐𝑖≥⌈𝑡𝑜𝑡3⌉ .
  • 我的做法是挨个遍历
  • 123
  • 132
  • 231
  • 213
  • 321
  • 312
  • 但是没做出来,超时了,300多行代码,自闭了。等有空我继续做
  • 换一种方式
    #include <iostream>
    #include <map>
    #include <queue>
    #include <algorithm>
    #include <vector>
    #include <cmath>
    #include <cstring>
    
    using namespace std;
    using ll = long long;
    
    const int N = 1e6;
    int a[4][N];
    ll cnt[4];
    int flag[4];
    int l1, l2, l3, r1, r2, r3;
    
    void solve() {
        int n;
        cin >> n;
    
        // 重置全局变量
        memset(a, 0, sizeof(a));
        memset(cnt, 0, sizeof(cnt));
        memset(flag, 0, sizeof(flag));
        l1 = l2 = l3 = r1 = r2 = r3 = 0;
    
        // 读取输入并计算前缀和
        for (int i = 1; i <= 3; ++i) {
            for (int j = 1; j <= n; ++j) {
                cin >> a[i][j];
                a[i][j] += a[i][j - 1];
            }
        }
    
        ll tot = (a[1][n] + 2) / 3;
        int start = 0;
    
        // 123 顺序
        for (int i = start + 1; i <= n; i++) {
            cnt[1] = a[1][i] - a[1][start];
            if (cnt[1] >= tot) {
                l1 = start + 1;
                r1 = i;
                start = i;
                flag[1] = 1;
                break;
            }
        }
        for (int i = start + 1; i <= n; i++) {
            cnt[2] = a[2][i] - a[2][start];
            if (cnt[2] >= tot) {
                l2 = start + 1;
                r2 = i;
                start = i;
                flag[2] = 1;
                break;
            }
        }
        for (int i = start + 1; i <= n; i++) {
            cnt[3] = a[3][i] - a[3][start];
            if (cnt[3] >= tot) {
                l3 = start + 1;
                r3 = i;
                start = i;
                flag[3] = 1;
                break;
            }
        }
    
        if (flag[1] && flag[2] && flag[3]) {
            cout << l1 << ' ' << r1 << ' ' << l2 << ' ' << r2 << ' ' << l3 << ' ' << r3 << "\n";
            return;
        }
        else {
            flag[1] = 0; flag[2] = 0; flag[3] = 0; start = 0;
            cnt[1] = 0; cnt[2] = 0; cnt[3] = 0;
        }
    
        // 132 顺序
        for (int i = start + 1; i <= n; i++) {
            cnt[1] = a[1][i] - a[1][start];
            if (cnt[1] >= tot) {
                l1 = start + 1;
                r1 = i;
                start = i;
                flag[1] = 1;
                break;
            }
        }
        for (int i = start + 1; i <= n; i++) {
            cnt[3] = a[3][i] - a[3][start];
            if (cnt[3] >= tot) {
                l3 = start + 1;
                r3 = i;
                start = i;
                flag[3] = 1;
                break;
            }
        }
        for (int i = start + 1; i <= n; i++) {
            cnt[2] = a[2][i] - a[2][start];
            if (cnt[2] >= tot) {
                l2 = start + 1;
                r2 = i;
                start = i;
                flag[2] = 1;
                break;
            }
        }
    
        if (flag[1] && flag[2] && flag[3]) {
            cout << l1 << ' ' << r1 << ' ' << l2 << ' ' << r2 << ' ' << l3 << ' ' << r3 << "\n";
            return;
        }
        else {
            flag[1] = 0; flag[2] = 0; flag[3] = 0; start = 0; cnt[1] = 0; cnt[2] = 0; cnt[3] = 0;
        }
    
        // 213 顺序
        for (int i = start + 1; i <= n; i++) {
            cnt[2] = a[2][i] - a[2][start];
            if (cnt[2] >= tot) {
                l2 = start + 1;
                r2 = i;
                start = i;
                flag[2] = 1;
                break;
            }
        }
        for (int i = start + 1; i <= n; i++) {
            cnt[1] = a[1][i] - a[1][start];
            if (cnt[1] >= tot) {
                l1 = start + 1;
                r1 = i;
                start = i;
                flag[1] = 1;
                break;
            }
        }
        for (int i = start + 1; i <= n; i++) {
            cnt[3] = a[3][i] - a[3][start];
            if (cnt[3] >= tot) {
                l3 = start + 1;
                r3 = i;
                start = i;
                flag[3] = 1;
                break;
            }
        }
    
        if (flag[1] && flag[2] && flag[3]) {
            cout << l1 << ' ' << r1 << ' ' << l2 << ' ' << r2 << ' ' << l3 << ' ' << r3 << "\n";
            return;
        }
        else {
            flag[1] = 0; flag[2] = 0; flag[3] = 0; start = 0; cnt[1] = 0; cnt[2] = 0; cnt[3] = 0;
        }
    
        // 231 顺序
        for (int i = start + 1; i <= n; i++) {
            cnt[2] = a[2][i] - a[2][start];
            if (cnt[2] >= tot) {
                l2 = start + 1;
                r2 = i;
                start = i;
                flag[2] = 1;
                break;
            }
        }
        for (int i = start + 1; i <= n; i++) {
            cnt[3] = a[3][i] - a[3][start];
            if (cnt[3] >= tot) {
                l3 = start + 1;
                r3 = i;
                start = i;
                flag[3] = 1;
                break;
            }
        }
        for (int i = start + 1; i <= n; i++) {
            cnt[1] = a[1][i] - a[1][start];
            if (cnt[1] >= tot) {
                l1 = start + 1;
                r1 = i;
                start = i;
                flag[1] = 1;
                break;
            }
        }
    
        if (flag[1] && flag[2] && flag[3]) {
            cout << l1 << ' ' << r1 << ' ' << l2 << ' ' << r2 << ' ' << l3 << ' ' << r3 << "\n";
            return;
        }
        else {
            flag[1] = 0; flag[2] = 0; flag[3] = 0; start = 0; cnt[1] = 0; cnt[2] = 0; cnt[3] = 0;
        }
    
        //312
        for (int i = start + 1; i <= n; i++) {
            cnt[3] = a[3][i] - a[3][start];
            if (cnt[3] >= tot) {
                l3 = start + 1;
                r3 = i;
                start = i;
                flag[3] = 1;
                break;
            }
        }
        for (int i = start + 1; i <= n; i++) {
            cnt[1] = a[1][i] - a[1][start];
            if (cnt[1] >= tot) {
                l1 = start + 1;
                r1 = i;
                start = i;
                flag[1] = 1;
                break;
            }
        }
        for (int i = start + 1; i <= n; i++) {
            cnt[2] = a[2][i] - a[2][start];
            if (cnt[2] >= tot) {
                l2 = start + 1;
                r2 = i;
                start = i;
                flag[2] = 1;
                break;
            }
        }
        if (flag[1] && flag[2] && flag[3]) {
            cout << l1 << ' ' << r1 << ' ' << l2 << ' ' << r2 << ' ' << l3 << ' ' << r3 << "\n";
            return;
        }
        else {
            flag[1] = 0; flag[2] = 0; flag[3] = 0; start = 0; cnt[1] = 0; cnt[2] = 0; cnt[3] = 0;
        }
        // 321 顺序
        for (int i = start + 1; i <= n; i++) {
            cnt[3] = a[3][i] - a[3][start];
            if (cnt[3] >= tot) {
                l3 = start + 1;
                r3 = i;
                start = i;
                flag[3] = 1;
                break;
            }
        }
        for (int i = start + 1; i <= n; i++) {
            cnt[2] = a[2][i] - a[2][start];
            if (cnt[2] >= tot) {
                l2 = start + 1;
                r2 = i;
                start = i;
                flag[2] = 1;
                break;
            }
        }
        for (int i = start + 1; i <= n; i++) {
            cnt[1] = a[1][i] - a[1][start];
            if (cnt[1] >= tot) {
                l1 = start + 1;
                r1 = i;
                start = i;
                flag[1] = 1;
                break;
            }
        }
    
        if (flag[1] && flag[2] && flag[3]) {
            cout << l1 << ' ' << r1 << ' ' << l2 << ' ' << r2 << ' ' << l3 << ' ' << r3 << "\n";
        }
        else {
            cout << "-1\n";
        }
    }
    
    int main() {
        ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
        int t;
        cin >> t;
        while (t--) {
            solve();
        }
        return 0;
    }

  • 10
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值