• noi.ac #529 神树的矩阵


    题目链接:戳我

    (max(n, m) ge 3) 时,可以如下构造:
    考虑下面这样三个矩阵,红 + 蓝 − 绿得到的矩阵是一个第一行和最后一行全是 1,其他地方全是 0 的矩阵。
    那么如果需要把中间某个位置变成 1,可以在红或蓝矩阵中的对应位置加一个 1。
    如果需要把第一行或最后一行某个位置变成 0,可以在绿矩阵中的对应位置加一个 1。


    然后对于其他情况分别特判就行了(具体哪些可以看main函数)

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<map>
    #define MAXN 510
    #define mp make_pair
    using namespace std;
    int n,m;
    int move_x[4]={0,0,1,-1},move_y[4]={1,-1,0,0};
    char s[MAXN][MAXN];
    namespace subtask_0
    {
        inline bool check()
        {
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    if(s[i][j]=='1')
                        return false;
            return true;
        }
    }
    namespace subtask_1
    {
        int done[MAXN][MAXN];
        inline bool bfs(int x,int y)//不带done的清空操作
        {
            queue<pair<int,int> >q;
            q.push(mp(x,y));
            while(!q.empty())
            {
                int u_x=q.front().first;
                int u_y=q.front().second;
                q.pop();
                done[u_x][u_y]=1;
                for(int k=0;k<=3;k++)
                {
                    int xx=u_x+move_x[k];
                    int yy=u_y+move_y[k];
                    if(xx<1||xx>n||yy<1||yy>m||s[xx][yy]=='0'||done[xx][yy]) continue;
                    done[xx][yy]=1;
                    q.push(mp(xx,yy));
                }
            }
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    if(s[i][j]=='1'&&done[i][j]==0) return false;
            return true;
        }
        inline bool check()
        {
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    if(s[i][j]=='1')
                    {
                        if(bfs(i,j)==true) return true;
                        else return false;
                    }
        }
        inline void solve()
        {
            printf("1
    +
    ");
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                    printf("%c",s[i][j]);
                puts("");
            }
        }
    }
    namespace subtask_2
    {
        int cnt,cur_ans,pos;
        int fa[MAXN*MAXN],id[MAXN][MAXN];
        map<int,int>ex;
        set<int>sset[MAXN*MAXN];
        inline int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}
        inline bool check()
        {
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    id[i][j]=++cnt,fa[cnt]=cnt;
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    for(int k=0;k<=3;k++)
                        {
                            int xx=i+move_x[k];
                            int yy=j+move_y[k];
                            if(xx<1||xx>n||yy<1||yy>m||s[i][j]!=s[xx][yy]) continue;
                            int t=find(id[i][j]),tt=find(id[xx][yy]);
                            if(t!=tt) fa[t]=tt;
                        }
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                {
                    if(s[i][j]=='0') continue;
                    int t=find(id[i][j]);
                    if(!ex.count(t)) ex[t]=1,cur_ans++;
                }
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                {
                    if(s[i][j]=='0')
                        for(int k=0;k<=3;k++)
                        {
                            int xx=i+move_x[k];
                            int yy=j+move_y[k];
                            if(xx<1||xx>n||yy<1||yy>m||s[xx][yy]=='0') continue;
                            int t=find(id[i][j]),tt=find(id[xx][yy]);
                            sset[t].insert(tt);
                        }
                }
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                    if(s[i][j]=='0')
                    {
                        int t=find(id[i][j]);
                        if((int)sset[t].size()==cur_ans)
                        {
                            pos=t;
                            break;
                        }
                    }
                if(pos!=0) break;
            }
            if(pos==0) return false;
            return true;
        }
        inline void solve()
        {
            printf("2
    +
    ");
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    if(s[i][j]=='1'||(s[i][j]=='0'&&find(id[i][j])==pos)) printf("1");
                    else printf("0");
                }
                puts("");
            }
            printf("-
    ");
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    if(s[i][j]=='0'&&find(id[i][j])==pos) printf("1");
                    else printf("0");
                }
                puts("");
            }
        }
    }
    inline void solve_n_1()
    {
        vector<pair<int,int> >vec;
        int now=1;
        while(now<=m)
        {
            int cnt1,cnt2;
            while(now<=m&&s[1][now]=='0') now++;
            if(now<=m&&s[1][now]=='1') 
            {
                cnt1=now;
                while(now<=m&&s[1][now]=='1') now++;
                cnt2=now-1;
                vec.push_back(mp(cnt1,cnt2));
            }
        }
        printf("%d
    ",(int)vec.size());
        for(int i=0;i<vec.size();i++)
        {
            printf("+
    ");
            for(int j=1;j<=m;j++)
            {
                if(vec[i].first<=j&&j<=vec[i].second) printf("1");
                else printf("0");
            }
            puts("");
        }
    }
    inline void solve_m_1()
    {
        vector<pair<int,int> >vec;
        int now=1;
        while(now<=n)
        {
            int cnt1,cnt2;
            while(now<=n&&s[now][1]=='0') now++;
            if(now<=n&&s[now][1]=='1') 
            {
                cnt1=now;
                while(now<=n&&s[now][1]=='1') now++;
                cnt2=now-1;
                vec.push_back(mp(cnt1,cnt2));
                // printf("[%d %d]
    ",cnt1,cnt2);
            }
        }
        printf("%d
    ",(int)vec.size());
        for(int i=0;i<vec.size();i++)
        {
            printf("+
    ");
            for(int j=1;j<=n;j++)
            {
                if(vec[i].first<=j&&j<=vec[i].second) printf("1
    ");
                else printf("0
    ");
            }
            // puts("");
        }
    }
    namespace others
    {
        char t[MAXN][MAXN],r[MAXN][MAXN],q[MAXN][MAXN];
        inline void print()
        {
            printf("3
    ");
            printf("+
    ");
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                    printf("%c",t[i][j]);
                puts("");
            }
            printf("+
    ");
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                    printf("%c",r[i][j]);
                puts("");
            }
            printf("-
    ");
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                    printf("%c",q[i][j]);
                puts("");
            }
        }
        inline void solve_m_2()
        {
            for(int i=1;i<=n;i++) 
            {
                t[i][1]='1';
                t[i][2]=(s[i][2]=='1'?'1':'0');
            }
            for(int i=1;i<=n;i++) 
            {
                r[i][2]='1';
                r[i][1]=(s[i][1]=='1'?'1':'0');
            }
            for(int i=1;i<=n;i++) q[i][1]=q[i][2]='1';
            print();
        }
        inline void solve()
        {
            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]=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]=='0'?'1':'0');
                q[i][m]=(s[i][m]=='0'?'1':'0');
                for(int j=2;j<m;j++) q[i][j]='1';
            }
            print();
        }
    }
    int main()
    {
        #ifndef ONLINE_JUDGE
        freopen("ce.in","r",stdin);
        // freopen("ce.out","w",stdout);
        #endif
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
        if(subtask_0::check()) printf("0
    ");
        else if(subtask_1::check()) subtask_1::solve();
        else if(subtask_2::check()) subtask_2::solve();
        else if(n==1) solve_n_1();
        else if(m==1) solve_m_1();
        else if(m==2) others::solve_m_2();
        else others::solve();
        return 0;
    }
    
  • 相关阅读:
    如何才能写一份好的简历?—— 针对程序员的简历。
    【视频】自然框架之分页控件的使用方法(二) 下载、DLL说明和web.config的设置
    【自然框架】QuickPager分页控件,新增一种分页方式——伪URL分页(Postback版)
    【自然框架】QuickPager asp.net 分页控件的Ajax分页方式。
    帮助文档的数据库结构
    自然框架,拆分后的项目关系
    【自然框架】QuickPagerSQL——专门生成分页用的SQL的类库
    【自然框架】QuickPager分页控件的单独的源码 V2.0.4.2。
    【自然框架】n级下拉列表框的原理
    分享一个基于jQuery的锁定表格行列的js脚本。
  • 原文地址:https://www.cnblogs.com/fengxunling/p/11134254.html
Copyright © 2020-2023  润新知