• Matrix Transformation codechef 数学题


    https://www.codechef.com/problems/MTRNSFRM

    我只能说codechef的题好劲爆,这题居然是easy的题,太可怕了。而且还有一点就是codechef的题解很难看懂╮( ̄▽ ̄")╭

    这题可以这样做,首先把两个矩阵合并在一起,然后就是变成了在一个矩阵C中,操作行和列的+1或者-1,最终使得整个矩阵为0。

    那么。对于每一行,的操作,我设为row[i],意思就是这一行进行的是什么操作,要么+,要么-,不可能又加又减的,因为都是整行的操作。然后同理设出col[j]。

    然后,如果有解,那么需要每个c[i][j] + row[i] + col[j] == 0恒成立。

    在上面的方程中,有两个未知数,因为其是互相独立的,那么特殊值一个先,先设i = 1

    有col[j] = -row[1] - c[1][j]  ① (这个就是col[j]的方程,因为只有j这个未知数)row[1]可以暴力出来,或者二分出来,反正是常数,那么带入去原来的式子,有:row[i] = row[1] + c[1][j] - c[i][j]

    同样是因为独立,所以特殊值那个j = 1,所以row[i] = row[1] + c[1][1] - c[i][1] ②

    有了上面两条式子,要判定c[i][j] + row[i] + col[j] == 0是否成立就简单了,带进去即可。

    求解:

    解的大小是sigma abs(row[i])   + sigma abs(col[j])

    目标是最小化这个函数。

    其中有一个x(row[1])是还没确定的呢。

    把公式拆开,就是sigma(abs(c[i][1] - c[1][1] - x)) + sigma(-c[1][j] - x)

    那么就是求一个点x,到c[i][1] - c[1][1]   和  -c[1][j]  这n + m个点的总和最小。

    中间值即可。

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <assert.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    #include <bitset>
    const int maxn = 1e5 + 20;
    vector<LL>a[maxn], ta[maxn];
    vector<LL>vc;
    void work() {
        int n, m;
        scanf("%d%d", &n, &m);
        vc.clear();
        for (int i = 1; i <= n; ++i) {
            a[i].clear();
            ta[i].clear();
            a[i].push_back(0);
        }
        for (int i = 1; i <= 2; ++i) {
            for (int j = 1; j <= n; ++j) {
                for (int k = 1; k <= m; ++k) {
                    LL x;
                    if (i == 1) {
                        scanf("%lld", &x);
                        a[j].push_back(x);
                    } else {
                        scanf("%lld", &x);
                        a[j][k] -= x;
                    }
                }
            }
        }
        for (int i = 1; i <= n; ++i) ta[i] = a[i];
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j <= m; ++j) {
                if (a[i][j] + a[1][1] - a[i][1] - a[1][j] != 0) {
                    cout << -1 << endl;
                    return;
                }
            }
        }
        vc.push_back(-((1LL) << 62));
        for (int i = 1; i <= n; ++i) {
            vc.push_back(a[i][1] - a[1][1]);
        }
        for (int j = 1; j <= m; ++j) {
            vc.push_back(-a[1][j]);
        }
        sort(vc.begin(), vc.end());
        LL ans = 0;
        for (int i = 1; i < vc.size(); ++i) {
            ans += abs(vc[i] - vc[(n + m + 1) / 2]);
        }
        cout << ans << endl;
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        int t;
        scanf("%d", &t);
        while (t--) work();
        return 0;
    }
    View Code
  • 相关阅读:
    微信开放平台:OpenAPI、云开发与基础管理能力升级
    腾讯刘颖:从容器到低代码,腾讯云原生技术演进历程
    十年老站长心声:我为什么选择把 Hexo 网站迁移到 Webify
    腾讯云发布微搭生态开放计划,与合作伙伴携手共创产业未来
    SQL Server附加数据库出现错误5123的正确解决方法
    数据分页获取(二)
    Select语句
    数据分页获取(一)
    SQL Server中行转列原理
    QT实现Linux下系统监控小工具之二
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6348095.html
Copyright © 2020-2023  润新知