• CF1366C Palindromic Paths(思维+并查集)


    题意:

    给出一个最大30*30的01矩阵,询问,最少修改几个节点,使得从起点(右上角)到终点(左下角)的所有路径全部为回文串。

    题解:

    考试的时候时间仓促,思考了正解的前面几步,最后的维护集合出了问题,思维还是要加强,不能C题都出不了。。。

    思路就是,两个距离起点和终点距离相同的点必定要一样,也就是同属于一个集合。最后对每个集合统计集合里0的数量和1的数量,取较小值,加起来即可。

    关键的一步在于集合的维护,考试的时候强行遍历所有节点,用并查集处理,这样会有O(N*N*M*M)的时间复杂度,最后TLE了。

    正解是,不用维护集合的信息,只要维护每个集合01节点的数量即可,那么每个节点所属的集合编号就是min(i+j,n+m+2-i-j),遇到两个坐标相反的节点就忽略,这样处理出每个集合的信息,时间复杂度O(N*M)。

    思维还是要练。光会并查集没啥用,要去主动的利用题目的性质优化算法。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1010;
    int a[maxn][maxn];
    int cnt1[maxn];
    int cnt2[maxn];
    int t,n,m;
    int main () {
        scanf("%d",&t);
        while (t--) {
            scanf("%d%d",&n,&m);
            for (int i=0;i<n+m;i++) cnt1[i]=cnt2[i]=0;
            for (int i=0;i<n;i++)
                for (int j=0;j<m;j++) {
                    scanf("%d",&a[i][j]);
                    int tt=i+j;
                    if (tt==n+m-2-i-j) continue;
                    tt=min(tt,n+m-2-i-j);
                    cnt1[tt]+=a[i][j];
                    cnt2[tt]++;
                 }
             int ans=0;
             for (int i=0;i<n+m;i++) ans+=min(cnt1[i],cnt2[i]-cnt1[i]);
             printf("%d
    ",ans);
        }
    }
  • 相关阅读:
    Django【进阶篇-缓存类型】
    深度剖析Kubernetes API Server三部曲
    深度剖析Kubernetes API Server三部曲
    深度剖析Kubernetes API Server三部曲
    Istio技术与实践03:最佳实践之sidecar自动注入
    原来你是这样的PaaS!
    5分钟APIG实战: 使用Rust语言快速构建API能力开放
    Log4J日志配置详解
    cookie是如何保存到客户端,又是如何发送到服务端
    session cookie
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/13098774.html
Copyright © 2020-2023  润新知