• Educational Codeforces Round 89 (Rated for Div. 2) C. Palindromic Paths(贪心)


    题目链接:https://codeforces.com/contest/1366/problem/C

    题意

    有一个 $n imes m$ 的 $01$迷宫,要使从 $(1,1)$ 到 $(n,m)$ 的所有路径均为回文串,至少要变换多少字符。

    题解一

    用 $bfs$ 得到回文串每个位置可能的 $01$ 个数,对称位置变换 $01$ 总个数中的较少值即可。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int dir[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
    const int N = 100;
    
    int n, m;
    int MP[N][N];
    bool vis[N][N];
    int cnt[N][2];
    
    bool inside(int x, int y) {
        return 1 <= x and x <= n and 1 <= y and y <= m;
    }
    
    struct P{
        int x, y, dep;
    };
    
    void bfs() {
        queue<P> que;
        que.push({1, 1, 1});
        vis[1][1] = true;
        while (!que.empty()) {
            int x = que.front().x;
            int y = que.front().y;
            int dep = que.front().dep;
            que.pop();
            ++cnt[dep][MP[x][y]];
            for (int i = 0; i < 4; i++) {
                int nx = x + dir[i][0];
                int ny = y + dir[i][1];
                if (inside(nx, ny) and !vis[nx][ny]) {
                    que.push({nx, ny, dep + 1});
                    vis[nx][ny] = true;
                }
            }
        }
    }
    
    void solve() {
        memset(vis, 0, sizeof vis);
        memset(cnt, 0, sizeof cnt);
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
                cin >> MP[i][j];
        bfs();
        int tot = n + m - 1;
        int ans = 0;
        for (int i = 1; i <= tot / 2; i++)
            ans += min(cnt[i][0] + cnt[tot - i + 1][0], cnt[i][1] + cnt[tot - i + 1][1]);
        cout << ans << "
    ";
    }
    
    int main() {
        int t; cin >> t;
        while (t--) solve();
    }

    题解二

    可以用下标计算出当前字符在 $bfs$ 中的层数,即回文串中的位置。

    代码

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 100;
    
    int n, m;
    int cnt[N][2];
    
    void solve() {
        memset(cnt, 0, sizeof cnt);
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++) {
                int x; cin >> x;
                ++cnt[i + j - 1][x];
            }
        int tot = n + m - 1;
        int ans = 0;
        for (int i = 1; i <= tot / 2; i++)
            ans += min(cnt[i][0] + cnt[tot - i + 1][0], cnt[i][1] + cnt[tot - i + 1][1]);
        cout << ans << "
    ";
    }
    
    int main() {
        int t; cin >> t;
        while (t--) solve();
    }
  • 相关阅读:
    SQLPrompt 7.2发布
    安装SQL Server2016正式版
    Coping with the TCP TIME-WAIT state on busy Linux servers
    分区里的inode号是0号和1号的block
    如何知道SQL Server机器上有多少个NUMA节点
    使用开源软件的原因
    一起来测试天兔Lepus3.8 Beta版本的MSSQL部分
    新书到手 TRANSACTION PROCESSING:CONCEPTS AND TECHNIQUES
    在线即时展现 Html、JS、CSS 编辑工具
    在触屏设备上面利用html5裁剪图片
  • 原文地址:https://www.cnblogs.com/Kanoon/p/13098240.html
Copyright © 2020-2023  润新知