NOJ [1301] Gopher Hole

一开始我没想到,如果原来有两个洞无法合并,加入第三个洞如果可以合并,那么三个洞就会变1个洞,所以原来写的WA了,后来参照了下题解的方法,才AC了,果然太弱了啊
  • Death-Moon loves telling stories. 
    Some days ago, he told us a funny story. 


    Long long ago, there is a hamster who is so naughty. Now, he comes to a place likes a N * N square. so, he is so excited to drill holes underground.


  • 输入
  • Input until EOF. 
    Fisrt input two integers N (3 <= N < 100) and M (0 < M <2000). N is the side of N * N ground, M is the number of operations. 

    Then follow M lines. 
    Each line is a command: 

    Out x y : Hamster will get out at (x, y) from underground. So, place (x, y) will be a hole. 
    P : Calculate out the number of the holes and output (Two holes are connected when they share an edge). 
    If two holes are connected, it means it is one hole. 
  • 输出
  • For each 'P' command, output the number of the holes. Maybe hamster will get out at the same place more than once. 

    #include<stdio.h>
    #include<string.h>
    #define maxn 10010
    bool is_break[maxn];
    int father[maxn];
    int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}};
    int is_not=0;
    int find(int x)
    {
      if(x==father[x])
        return father[x];
      if(x!=father[x])
        father[x]=find(father[x]);
      return father[x];
    }
    
    void Union(int x,int y)
    {
      int xx=find(x);
      int yy=find(y);
      if(xx!=yy)
      {
        father[yy]=xx;
        is_not--;
      }
    }
    
    int main()
    {
      int n,m,i,j;
      while(~scanf("%d%d",&n,&m))
      {
        for(i=0;i<=n*n+10;i++)
          father[i]=i;
        memset(is_break,false,sizeof(is_break));
        char com[4];
        int x,y,xx,yy,ans=0,dit;
        while(m--)
        {
          scanf("%s",com);
          if(com[0]=='O')
          {
            scanf("%d%d",&x,&y);
            dit=x*n+y;
            if(is_break[dit])
              continue;
            is_break[dit]=1;
            for(j=0;j<4;j++)
            {
              xx=x+dir[j][0];
              yy=y+dir[j][1];
              if(xx>=0 && yy>=0 && xx<n && yy<n)
              {
                if(is_break[xx*n+yy]==0)
                 continue;
              else
                 break;
              }
            }
            if(j==4)
            {
              ans++;
              continue;
            }
            is_not=1;
            for(j=0;j<4;j++)
            {
              xx=x+dir[j][0];
              yy=y+dir[j][1];
              if(xx<0 || yy<0 || xx>=n || yy>=n || is_break[xx*n+yy]==0)
                continue;
              else
                Union(dit,xx*n+yy);
            }
            ans+=is_not;
          }
          else if(com[0]=='P')
            printf("%d\n",ans );
        }
      }
      return 0;
    }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值