表示今天一发A了这题拿了rk3...是个sb构造...

考虑除了\(n=1/m=1\)的情况,最小次数\(ans\)不会\(>3\)。

对于\(n=1/m=1\),暴力即可。

然后考虑\(ans=0\),只有在图中没有\(1\)时成立。

对于\(ans=1\),图中的\(1\)是一个四联通块

对于\(ans=2\),加入图中的某个\(0\)的四联通块后所有的\(1\)是一个四联通块。

对于其他的情况,若\(\max(n,m)<3\),显然只有\(n=m=2\),枚举\(16\)种情况发现\(ans\leq 2\)。

所以考虑有\(\max(n,m)\geq 3\),此时一定可以构造出\(ans=3\)的合法方案。构造方式如下:

  • 不妨设\(n\leq m\),则\(m\geq3\)。
  • 两个矩阵为+,一个矩阵为-
  • 将第一个矩阵的第一列和奇数行的第二列到第\(m-1\)列设为\(1\)。
  • 将第二个矩阵的第\(m\)列和偶数行的第二列到第\(m-1\)列设为\(1\)。
  • 将两个矩阵第二列到第\(m-1\)列在目标矩阵中的对应位置为\(1\)的位置设为\(1\)(此时一定满足四联通性质)。
  • 将第三个矩阵的第二列到第\(m-1\)列设为\(1\),第一列和第\(m\)列在目标矩阵中的对应位置为\(0\)的位置设为\(1\)。

此时一定可以构造出合法的方案,\(ans=3\)。

槽点:这题\(n,m\leq500\)挺垃圾的,为什么不开\(n,m\leq5000\)(虽说得稍微改一下实现)。

放代码:代码里面有些重复的东西是复制出来的所以看起来可能会有点丑...

#include<bits/stdc++.h>

using namespace std;

const int N=502,fx[2][4]={{0,0,1,-1},{1,-1,0,0}};

int n,m;

char s[N][N],t[N][N],r[N][N],q[N][N];

int vis[N][N],cnt[2];

bool check0(){
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(s[i][j]=='1'){
                return 0;
            }
        }
    }
    return 1;
}

void solve0(){
    printf("0\n");
}

void dfs1(int u,int v){
    if(vis[u][v]){
        return;
    }
    vis[u][v]=1;
    for(int i=0,tx,ty;i<4;i++){
        tx=u+fx[0][i];ty=v+fx[1][i];
        if(tx<1||ty<1||tx>n||ty>m){
            continue;
        }
        if(s[tx][ty]=='1'&&!vis[tx][ty]){
            dfs1(tx,ty);
        }
    }
}

bool check1(){
    memset(vis,0,sizeof vis);
    bool flag=1;
    for(int i=1;i<=n;i++){
        if(!flag){
            break;
        }
        for(int j=1;j<=m;j++){
            if(s[i][j]=='1'){
                dfs1(i,j);
                flag=0;
                break;
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(s[i][j]=='1'){
                if(!vis[i][j]){
                    return 0;
                }
            }
        }
    }
    return 1;
}

void solve1(){
    printf("1\n+\n");
    for(int i=1;i<=n;i++){
        printf("%s\n",s[i]+1);
    }
}

set<int>st;

void dfs2(int u,int v,int w){
    if(vis[u][v]){
        return;
    }
    vis[u][v]=w;
    for(int i=0,tx,ty;i<4;i++){
        tx=u+fx[0][i];ty=v+fx[1][i];
        if(tx<1||ty<1||tx>n||ty>m){
            continue;
        }
        if(s[tx][ty]=='0'&&!vis[tx][ty]){
            dfs2(tx,ty,w);
        }
        else if(s[tx][ty]=='1'){
            st.insert(vis[tx][ty]);
        }
    }
}

void dfs21(int u,int v,int w){
    if(vis[u][v]){
        return;
    }
    vis[u][v]=w;
    for(int i=0,tx,ty;i<4;i++){
        tx=u+fx[0][i];ty=v+fx[1][i];
        if(tx<1||ty<1||tx>n||ty>m){
            continue;
        }
        if(s[tx][ty]=='1'&&!vis[tx][ty]){
            dfs21(tx,ty,w);
        }
    }
}

bool check2(){
    memset(vis,0,sizeof vis);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(s[i][j]=='1'&&!vis[i][j]){
                dfs21(i,j,++cnt[1]);
            }
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(s[i][j]=='0'&&!vis[i][j]){
                st.clear();
                dfs2(i,j,++cnt[0]);
                if((int)st.size()==cnt[1]){
                    return 1;
                }
            }
        }
    }
    return 0;
}

void solve2(){
    printf("2\n");
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            t[i][j]=s[i][j];
            q[i][j]='0';
            if(s[i][j]=='0'&&vis[i][j]==cnt[0]){
                t[i][j]='1';q[i][j]='1';
            }
        }
    }
    printf("+\n");
    for(int i=1;i<=n;i++){
        printf("%s\n",t[i]+1);
    }
    printf("-\n");
    for(int i=1;i<=n;i++){
        printf("%s\n",q[i]+1);
    }
}

int lb[N],rb[N];

void solven1(){
    memset(vis,0,sizeof vis);
    memset(cnt,0,sizeof cnt);
    memset(lb,0x3f,sizeof lb);
    for(int i=1;i<=m;i++){
        if(s[1][i]=='1'){
            if(vis[1][i]){
                continue;
            }
            dfs21(1,i,++cnt[1]);
        }
    }
    for(int i=1;i<=m;i++){
        if(vis[1][i]){
            lb[vis[1][i]]=min(lb[vis[1][i]],i);
            rb[vis[1][i]]=max(rb[vis[1][i]],i);
        }
    }
    int ans=cnt[1],lmt,ll=1,rr=cnt[1];
    printf("%d\n",ans);
    if(cnt[1]&1){
        lmt=ans>>1;
        for(int i=1;i<=lmt;i++){
            printf("+\n");
            for(int j=1;j<=m;j++){
                t[1][j]='0';
            }
            for(int j=lb[ll];j<=rb[rr];j++){
                t[1][j]='1';
            }
            printf("%s\n",t[1]+1);
            printf("-\n");
            for(int j=1;j<=m;j++){
                t[1][j]='0';
            }
            for(int j=rb[ll]+1;j<lb[rr];j++){
                t[1][j]='1';
            }
            printf("%s\n",t[1]+1);
            ll++;rr--;
        }
        for(int j=1;j<=m;j++){
            t[1][j]='0';
        }
        for(int j=lb[ll];j<=rb[ll];j++){
            t[1][j]='1';
        }
        printf("+\n");
        printf("%s\n",t[1]+1);
    }
    else{
        lmt=ans>>1;
        for(int i=1;i<=lmt;i++){
            printf("+\n");
            for(int j=1;j<=m;j++){
                t[1][j]='0';
            }
            for(int j=lb[ll];j<=rb[rr];j++){
                t[1][j]='1';
            }
            printf("%s\n",t[1]+1);
            printf("-\n");
            for(int j=1;j<=m;j++){
                t[1][j]='0';
            }
            for(int j=rb[ll]+1;j<lb[rr];j++){
                t[1][j]='1';
            }
            printf("%s\n",t[1]+1);
            ll++;rr--;
        }
    }
}

void solvem1(){
    memset(vis,0,sizeof vis);
    memset(cnt,0,sizeof cnt);
    memset(lb,0x3f,sizeof lb);
    for(int i=1;i<=n;i++){
        if(s[i][1]=='1'){
            if(vis[i][1]){
                continue;
            }
            dfs21(i,1,++cnt[1]);
        }
    }
    for(int i=1;i<=n;i++){
        if(vis[i][1]){
            lb[vis[i][1]]=min(lb[vis[i][1]],i);
            rb[vis[i][1]]=max(rb[vis[i][1]],i);
        }
    }
    int ans=cnt[1],lmt,ll=1,rr=cnt[1];
    printf("%d\n",ans);
    if(cnt[1]&1){
        lmt=ans>>1;
        for(int i=1;i<=lmt;i++){
            printf("+\n");
            for(int j=1;j<=n;j++){
                t[j][1]='0';
            }
            for(int j=lb[ll];j<=rb[rr];j++){
                t[j][1]='1';
            }
            for(int j=1;j<=n;j++){
                printf("%s\n",t[j]+1);
            }
            printf("-\n");
            for(int j=1;j<=n;j++){
                t[j][1]='0';
            }
            for(int j=rb[ll]+1;j<lb[rr];j++){
                t[j][1]='1';
            }
            for(int j=1;j<=n;j++){
                printf("%s\n",t[j]+1);
            }
            ll++;rr--;
        }
        for(int j=1;j<=n;j++){
            t[j][1]='0';
        }
        for(int j=lb[ll];j<=rb[ll];j++){
            t[j][1]='1';
        }
        printf("+\n");
        for(int j=1;j<=n;j++){
            printf("%s\n",t[j]+1);
        }
    }
    else{
        lmt=ans>>1;
        for(int i=1;i<=lmt;i++){
            printf("+\n");
            for(int j=1;j<=n;j++){
                t[j][1]='0';
            }
            for(int j=lb[ll];j<=rb[rr];j++){
                t[j][1]='1';
            }
            for(int j=1;j<=n;j++){
                printf("%s\n",t[j]+1);
            }
            printf("-\n");
            for(int j=1;j<=n;j++){
                t[j][1]='0';
            }
            for(int j=rb[ll]+1;j<lb[rr];j++){
                t[j][1]='1';
            }
            for(int j=1;j<=n;j++){
                printf("%s\n",t[j]+1);
            }
            ll++;rr--;
        }
    }
}

void ssolve(){
    printf("3\n");
    for(int i=1;i<=m;i++){
        t[1][i]='1';t[n][i]='0';
        r[1][i]='0';r[n][i]='1';
        for(int j=2;j<n;j++){
            t[j][i]=s[j][i];r[j][i]=s[j][i];
        }
        if(i&1){
            for(int j=1;j<n;j++){
                t[j][i]='1';
            }
        }
        else{
            for(int j=2;j<=n;j++){
                r[j][i]='1';
            }
        }
    }
    for(int i=1;i<=m;i++){
        q[1][i]=(s[1][i]!='1'?'1':'0');
        q[n][i]=(s[n][i]!='1'?'1':'0');
        for(int j=2;j<n;j++){
            q[j][i]='1';
        }
    }
    printf("+\n");
    for(int i=1;i<=n;i++){
        printf("%s\n",t[i]+1);
    }
    printf("+\n");
    for(int i=1;i<=n;i++){
        printf("%s\n",r[i]+1);
    }
    printf("-\n");
    for(int i=1;i<=n;i++){
        printf("%s\n",q[i]+1);
    }
}

void solve(){
    printf("3\n");
    for(int i=1;i<=n;i++){
        t[i][1]='1';t[i][m]='0';
        r[i][1]='0';r[i][m]='1';
        for(int j=2;j<m;j++){
            t[i][j]=s[i][j];r[i][j]=s[i][j];
        }
        if(i&1){
            for(int j=1;j<m;j++){
                t[i][j]='1';
            }
        }
        else{
            for(int j=2;j<=m;j++){
                r[i][j]='1';
            }
        }
    }
    for(int i=1;i<=n;i++){
        q[i][1]=(s[i][1]!='1'?'1':'0');
        q[i][m]=(s[i][m]!='1'?'1':'0');
        for(int j=2;j<m;j++){
            q[i][j]='1';
        }
    }
    printf("+\n");
    for(int i=1;i<=n;i++){
        printf("%s\n",t[i]+1);
    }
    printf("+\n");
    for(int i=1;i<=n;i++){
        printf("%s\n",r[i]+1);
    }
    printf("-\n");
    for(int i=1;i<=n;i++){
        printf("%s\n",q[i]+1);
    }
}

int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%s",s[i]+1);
    }
    if(check0()){
        solve0();return 0;
    }
    if(check1()){
        solve1();return 0;
    }
    if(check2()){
        solve2();return 0;
    }
    if(n==1){
        solven1();return 0;
    }
    if(m==1){
        solvem1();return 0;
    }
    if(m==2){
        ssolve();
    }
    else{
        solve();
    }
    return 0;
}

noi.ac NA529 【神树的矩阵】的更多相关文章

  1. noi.ac #529 神树的矩阵

    题目链接:戳我 当 \(max(n, m) \ge 3\) 时,可以如下构造: 考虑下面这样三个矩阵,红 + 蓝 − 绿得到的矩阵是一个第一行和最后一行全是 1,其他地方全是 0 的矩阵. 那么如果需 ...

  2. noi.ac #531 神树和物品

    题目链接:戳我 决策单调性 (蒟蒻终于会写决策单调性啦!考试全场切这题就我不会啊嘤) (证明?不会啊,自己打表看QAQ) 44pts \(O(n^2)\)代码: #include<iostrea ...

  3. noi.ac #528 神树和排列

    题目链接:戳我 #include<iostream> #include<cstring> #include<cstdio> #include<algorith ...

  4. noi.ac #525 神树的权值

    mcfx神仙的题qwq 题目链接:戳我 首先,我们知道30%的分还是挺好做的 直接枚举根,然后dfs一遍以\(O(n)\)的时间复杂度求出来有多少神仙点 代码如下: #include<iostr ...

  5. NOI.AC NOIP模拟赛 第三场 补记

    NOI.AC NOIP模拟赛 第三场 补记 列队 题目大意: 给定一个\(n\times m(n,m\le1000)\)的矩阵,每个格子上有一个数\(w_{i,j}\).保证\(w_{i,j}\)互不 ...

  6. # NOI.AC省选赛 第五场T1 子集,与&最大值

    NOI.AC省选赛 第五场T1 A. Mas的童年 题目链接 http://noi.ac/problem/309 思路 0x00 \(n^2\)的暴力挺简单的. ans=max(ans,xor[j-1 ...

  7. NOI.ac #31 MST DP、哈希

    题目传送门:http://noi.ac/problem/31 一道思路好题考虑模拟$Kruskal$的加边方式,然后能够发现非最小生成树边只能在一个已经由边权更小的边连成的连通块中,而树边一定会让两个 ...

  8. NOI.AC NOIP模拟赛 第五场 游记

    NOI.AC NOIP模拟赛 第五场 游记 count 题目大意: 长度为\(n+1(n\le10^5)\)的序列\(A\),其中的每个数都是不大于\(n\)的正整数,且\(n\)以内每个正整数至少出 ...

  9. NOI.AC NOIP模拟赛 第六场 游记

    NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...

随机推荐

  1. 怎么在 localhost 下访问多个 Laravel 项目,通过一个IP访问多个项目(不仅仅是改变端口哦)

    server { listen 80; server_name blog.sweetsunnyflower.com; index index.html index.htm index.php; cha ...

  2. TensorFlow 用神经网络解决非线性问题

    本节涉及点: 激活函数 sigmoid 产生随机训练数据 使用随机训练数据训练 加入偏移量b加快训练过程 进阶:批量生产随机训练数据 在前面的三好学生问题中,学校改变了评三好的标准 —— 总分> ...

  3. 【HANA系列】【第七篇】SAP HANA XS使用Data Services查询CDS实体【一】

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列][第七篇]SAP HANA XS ...

  4. ASP.NET Core 入门笔记2,建立项目

    1.建立项目 2.项目结构 1.项目结构说明 根目录/文件 说明 .vscode目录 VS Code项目配置目录,相当于.vs..idea文件夹 bin目录 编译输出目录 obj目录 编译配置与中间目 ...

  5. nginx +域名

    文件nginx.config: server { listen 80 ; server_name dns19.hichina.com;location / { proxy_pass http://12 ...

  6. 应用安全 - 工具|平台 - Elasticsearch- 漏洞 - 汇总

    未授权访问 (1)/_cat/indices #Index个数查询 (2)/_mapping?pretty=true #type个数查询 (3)根据Index和type查询表数据 (4)/_river ...

  7. finereport 填报 单元格 JS 触发 提交SQL 事件

    var location = this.options.location; var cr = FR.cellStr2ColumnRow(location); var col = cr.col; var ...

  8. 【C/C++】什么是类型安全

    什么是类型安全 转自:http://hi.baidu.com/chenfalei/blog/item/f33ac0133500ac21dd540186.html 编程语言的最终梦想:静态类型安全 常听 ...

  9. 解决Iframe跨域高度自适应,利用window.postMessage()实现跨域消息传递页面高度(JavaScript)

    在iframe跨域引用高度自适应这块写的js方式都试了不管用,最终使用的是window.postMessage() 跨域获取高度 传递信息 1.首先,在主页面上使用iframe引入子页面:也就是A.h ...

  10. springmvc的MultipartFile参数如果不上传文件报错的问题

    @RequestMapping(value = "/updateInformation",method = RequestMethod.POST) @ResponseBody pu ...