题意:给你11种类型的管道,给你一片农田,让这些管道里面的水流到所有的农田,问你对少要安装多少个碰头。
想法:大一的时候遇到不敢做,不知道怎么做。今天一眼看过去,会了,只是需要积淀的。这里注意一点,方向是题目规定的,只要把每一个管道类型记录,每次搜索农田,然后按照本农田的管道方向搜索,然后只要管道的方向和那个方向的农田的反方向管道连接,那么就可以了,其他的地方和油田那题一样,简单的广搜。
#include<iostream> #include<cstring> #include<cstdio> #include<queue> using namespace std; int n,m; char map[60][60]; int vis[60][60]; struct node { int x,y; }d[60*60]; int dir[11][4][2]={//都是按照上下左右的方向 {-1,0,0,0,0,-1,0,0}, {-1,0,0,0,0,0,0,1}, {0,0,1,0,0,-1,0,0}, {0,0,1,0,0,0,0,1}, {-1,0,1,0,0,0,0,0}, {0,0,0,0,0,-1,0,1}, {-1,0,0,0,0,-1,0,1}, {-1,0,1,0,0,-1,0,0}, {0,0,1,0,0,-1,0,1}, {-1,0,1,0,0,0,0,1}, {-1,0,1,0,0,-1,0,1} }; int judgedir(int x,int y) { return map[x][y]-'A'; } int conjudge(int k,int fangxiang,int kk) { if(fangxiang==0) { if(dir[kk][1][0]==0&&dir[kk][1][1]==0) return 0; } if(fangxiang==1) { if(dir[kk][0][0]==0&&dir[kk][0][1]==0) return 0; } if(fangxiang==2) { if(dir[kk][3][0]==0&&dir[kk][3][1]==0) return 0; } if(fangxiang==3) { if(dir[kk][2][0]==0&&dir[kk][2][1]==0) return 0; } return 1; } void bfs(int x,int y) { queue<node>q; while(!q.empty()) q.pop(); node head,tail; head.x=x; head.y=y; vis[x][y]=1; q.push(head); while(!q.empty()) { head=q.front(); q.pop(); int k=judgedir(head.x,head.y); for(int i=0;i<4;i++) { int xx=dir[k][i][0]+head.x; int yy=dir[k][i][1]+head.y; if(xx==0&&yy==0) continue; tail.x=xx;tail.y=yy; if(tail.x<0||tail.x>=n||tail.y<0||tail.y>m) continue; int kk=judgedir(tail.x,tail.y); if(!conjudge(k,i,kk)) continue; if(!vis[tail.x][tail.y]) { vis[tail.x][tail.y]=1; q.push(tail); } } } return; } void Input() { for(int i=0;i<n;i++) scanf("%s",map[i]); } void treatment() { int cnt=0; memset(vis,0,sizeof(vis)); for(int i=0;i<n;i++) { for(int j=0;j<m;j++) { if(vis[i][j]) continue; bfs(i,j); cnt++; } } printf("%d\n",cnt); } int main() { while(~scanf("%d%d",&n,&m)) { if(n==-1&&m==-1) break; Input(); treatment(); } return 0; }