HDU 1198

来源:互联网 发布:淘宝店铺首页大图图片 编辑:程序博客网 时间:2024/05/18 00:11

从并查集的角度来说这就是一道水题,重点是判断两个节点之间能不能合并在一起,我选择的是结构数组,不过也可以用int数组用4位的二进制来表示上下左右四个方向能否联通,还有在并查集的时候要分上下和左右来搜索,主要涉及到边界的问题。这个地方WA了很多次,后面在意识到。

#include<stdio.h>#include<string.h>int father[2550];char map[550][550];int n,m;struct print{    int up,down,left,right;};print s[11]={{1,0,1,0},{1,0,0,1},{0,1,1,0},{0,1,0,1},{1,1,0,0},{0,0,1,1},{1,0,1,1},{1,1,1,0},{0,1,1,1},{1,1,0,1},{1,1,1,1}};int find(int x){    if(x==father[x]) return x;    else        return father[x]=find(father[x]);}void unite(int x,int y){    int xx=find(x);    int yy=find(y);    if(xx==yy) return ;    else        father[yy]=xx;        return;}int main(){    int ans;    while(scanf("%d%d",&m,&n)){    for(int i=0;i<n*m;i++) father[i]=i;        if(n<0||m<0) break;        for(int i=0;i<m;i++) scanf("%s",map[i]);        for(int i=1;i<m;i++)          for(int j=0;j<n;j++)          {              if(s[map[i][j]-'A'].up==1&&s[map[i-1][j]-'A'].down==1)                  unite(i*n+j,(i-1)*n+j);          }        for(int i=0;i<m;i++)          for(int j=1;j<n;j++)          {              if(s[map[i][j]-'A'].left==1&&s[map[i][j-1]-'A'].right==1)                   unite(i*n+j,i*n+j-1);          }        ans=0;        for(int i=0;i<n*m;i++){            if(father[i]==i) ans++;        }        printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击