Description
Input
Output
Sample Input
2 2 DK HF 3 3 ADC FJK IHE -1 -1
Sample Output
2 3
题目大意是说:看,上面有张图表,分别A-K,对应不同的管道图。然后输入一个字母网格,看对应的管道图有几个在一堆,有几堆就打几个水桩。
自然就想到并查集,只是这里要处理一下,A-K的图,用一个结构体数组表示,1表示某个方向有接口,0表示没有,便于后面集合合并判断。看到别的大牛还有用二进制数表示的,直接位运算。高!改天我也试一下。
#include <stdio.h> #define N 360000 int a[600][600],father[600][600]; typedef struct { int u,d,l,r; }Grid; Grid grid[]={{0,0,0,0},{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 fa[10000],size[10000]; void InitSet(int n){ for(int i=1; i<=n; i++) { fa[i] = i; size[i]=1; } } int Find(int x) { return fa[x] == x ? x : fa[x] = Find(fa[x]) ; } void Merge(int u ,int v) { int fu = Find(u) , fv = Find(v) ; if(fu != fv) { fa[fv] = fu ; size[fu] += size[fv]; size[fv] = 0 ; } } int main() { int m,n; while(scanf("%d%d",&m,&n)) { if(m<1||n<1) break; InitSet(m*n); char temp; for(int i=1;i<=m;i++) { getchar(); for(int j=1;j<=n;j++) { scanf("%c",&temp); a[i][j]=temp-64; } } int k=1; for(int i=1;i<=m;i++) for(int j=1;j<=n;j++) father[i][j]=k++; for(int i=1;i<=m;i++) { for(int j=1;j<=n;j++) { if(grid[a[i][j-1]].r&&grid[a[i][j]].l) { Merge(father[i][j-1],father[i][j]); } if(grid[a[i-1][j]].d&&grid[a[i][j]].u) { Merge(father[i-1][j],father[i][j]); } } } int ans=0; for(int i=1;i<=m*n;i++) { if(size[i]) ans++; } printf("%d\n",ans); } return 0; }