【洛谷p1162】填涂颜色

(今天yy出奇的不活泼,认真的吓人)

【传送门】

算法标签:


思路啊qwq:

  • part1:

  • 想法是先暴搜出每一行的1,取最前方一个1和最后方一个1,然后中间的0填上色,80分,因为没有考虑到“00011100101”这样类似的的情况。
  • #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    using namespace std;
    int n,minx=1000000,miny[50],maxx,maxy[50];
    int a[50][50],ans[50][2];
    bool vis[50][50];
    int dx[4]={1,0,-1,0};
    int dy[4]={0,1,0,-1};
    struct az{
        int x,y;
    };
    az fz(int x,int y){
        az rtn;
        rtn.x=x;
        rtn.y=y;
        return rtn;
    }
    bool pan(int x,int y){
        return x>=1&&y>=1&&x<=n&&y<=n&&vis[x][y]==0;
    }
    queue<az> q;
    void bfs(){
        q.push(fz(1,1));
        vis[1][1]=1;
        int num=0;
        while(!q.empty()){
            az h=q.front();
            q.pop();
            for(int i=0;i<4;i++){
                int xx=h.x,yy=h.y;
                if(pan(xx+dx[i],yy+dy[i])){
                    xx+=dx[i];
                    yy+=dy[i];
                    if(a[xx][yy]==1){
                        ans[++num][0]=xx;
                        ans[num][1]=yy;
                        if(xx<minx)minx=xx;if(xx>maxx)maxx=xx;
                        if(yy>maxy[xx])maxy[xx]=yy;
                        if(yy<miny[xx])miny[xx]=yy;
                    }
                    q.push(fz(xx,yy));
                    vis[xx][yy]=1;
                }
            }
        }
        for(int i=minx;i<=maxx;i++)
            for(int j=miny[i];j<=maxy[i];j++)
                if(a[i][j]==0)
                a[i][j]=2;
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
          scanf("%d",&a[i][j]);
          memset(miny,63,sizeof(miny));
        bfs();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++)
            cout<<a[i][j]<<" ";
            cout<<endl;
        }
    }

    然后下载了最后一个数据,我做了一个伟大的打表水数据的决定qwq:

  • 但是良心不安啊,于是我又想了一个神奇的思路:
  • 根据题意,当找到第一个1时,其右下必然是圈内的0,那么只要从这个0开始广搜寻找联通块就可以了。
  • 所以就这这个写了一个程序:
  • #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<cstdio>
    #include<queue>
    #include<cmath>
    using namespace std;
    int n,sy,sx;
    int a[50][50];
    bool vis[50][50],b;
    int dx[4]={1,0,-1,0};
    int dy[4]={0,1,0,-1};
    bool panduan(int x,int y){
        
    }
    struct az{
        int x,y;
    };
    az fz(int x,int y){
        az rtn;
        rtn.x=x;
        rtn.y=y;
        return rtn;
    }
    bool pan(int x,int y){
        return x>=1&&y>=1&&x<=n&&y<=n&&vis[x][y]==0;
    }
    queue<az> q;
    void bfs(){
        q.push(fz(1,1));
        vis[1][1]=1;
        int num=0;
        while(!q.empty()){
            az h=q.front();
            q.pop();
            for(int i=0;i<4;i++){
                int xx=h.x,yy=h.y;
                if(a[xx][yy]==1){
                        sx=xx+1;
                        sy=yy+1;
                        b=1;
                        break;
                }
                if(pan(xx+dx[i],yy+dy[i])){
                    xx+=dx[i];
                    yy+=dy[i];
                    q.push(fz(xx,yy));
                    vis[xx][yy]=1;
                }
            }
            if(b==1)break;
        }
        queue<az> Q;
        Q.push(fz(sx,sy));
        a[sx][sy]=2;
        while(!Q.empty()){
            az hh=Q.front();
            Q.pop();
            for(int i=0;i<4;i++){
                int aa=hh.x,bb=hh.y;
                aa+=dx[i];
                bb+=dy[i];
                if(a[aa][bb]==0){
                    Q.push(fz(aa,bb));
                    a[aa][bb]=2;
                }
                
            }
        }
    }
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
          scanf("%d",&a[i][j]);
        bfs();
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++)
            cout<<a[i][j]<<" ";
            cout<<endl;
        }
    }

    end-

原文地址:https://www.cnblogs.com/zhuier-xquan/p/10745883.html