zoukankan      html  css  js  c++  java
  • 【洛谷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-

  • 相关阅读:
    《第三周作业》——第四小组
    《UML与设计原则》--第四小组
    《我与计算机》——第四小组
    PSP数据比较(四则运算)——计应193第6组栗亚文
    个人工作流程(地铁收费系统)——计应193第6组张淑雅
    设计模式学习总结
    行为型模式总结
    UML第二部分和创建型模式的总结(二)
    UML第二部分和创建型模式的总结
    UML第一部分和设计模式原则的总结
  • 原文地址:https://www.cnblogs.com/zhuier-xquan/p/10745883.html
Copyright © 2011-2022 走看看