【HDU 1198】Farm Irrigation(字符串拼接/类油田问题/DFS)

Farm Irrigation

Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u

Description

Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot of samll squares. Water pipes are placed in these squares. Different square has a different type of pipe. There are 11 types of pipes, which is marked from A to K, as Figure 1 shows.

Figure 1
这里写图片描述

Benny has a map of his farm, which is an array of marks denoting the distribution of water pipes over the whole farm. For example, if he has a map

ADC
FJK
IHE

then the water pipes are distributed like

Figure 2
这里写图片描述

Several wellsprings are found in the center of some squares, so water can flow along the pipes from one square to another. If water flow crosses one square, the whole farm land in this square is irrigated and will have a good harvest in autumn.

Now Benny wants to know at least how many wellsprings should be found to have the whole farm land irrigated. Can you help him?

Note: In the above example, at least 3 wellsprings are needed, as those red points in Figure 2 show.

Input

There are several test cases! In each test case, the first line contains 2 integers M and N, then M lines follow. In each of these lines, there are N characters, in the range of ‘A’ to ‘K’, denoting the type of water pipe over the corresponding square. A negative M or N denotes the end of input, else you can assume 1 <= M, N <= 50.

Output

For each test case, output in one line the least number of wellsprings needed.

Sample Input

2 2
DK
HF

3 3
ADC
FJK
IHE

-1 -1

Sample Output

2
3

题目意思:连通起来的水管是一个区域,你找出区域数就行

解析:看到这题的时候,我仔细想了下。这个不就是油田问题那个搜索的变种吗。只不过我们需要将几个二维字符串拼接成一个大的二维字符串一样。

比如下面定义好的水管形状用字符串表示:

A: .#.  B: .#.
   ##.     .##
   ...     ...

**将所有水管形状给初始化好,就可以开始搞了。

我们按照输入的字符是’A’还是其他,将每次的一个二维字符串(表示水管形状的)放进一个中间二维字符串中:void xz(int i,int j);

然后我们就一个一个的接起来,等于模拟它接水管的过程(拼图)。

拼接字符串核心代码:

for(int i=0 ; i<n*3 ; i++){
        for(int j=0 ; j<m*3 ; j++){
            k=i/3;
            t=j/3;
            xz(k,t);
            map[i][j]=tem[i%3][j%3];
        }
    }
}

效果有:
这里写图片描述

我们的地图字符串就好了。
开始用搞油田那一套弄上去

首先找到一个’#’把他能上下左右走到的是’#’的全部弄成’.’,同时记录联通的水管的个数+1,再开始寻找下一个’#’。

附上代码:

#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"

using namespace std;

const int maxn =1e3+5;
int n,m;

int changeX[4]={
   
   0,0,-1,1};
int changeY[4]={
   
   1,-1,0,0};
char tem[4][4];
char sr[55][55];
char map[maxn][maxn];

char A[4][4]={
   
   ".#.","##.","..."};
char B[4][4]={
   
   ".#.",".##","..."};
char C[4][4]={
   
   "...","##.",".#."};
char D[4][4]={
   
   "...",".##",".#."};
char E[4][4]={
   
   ".#.",".#.",".#."};
char F[4][4]={
   
   "...","###","..."};
char G[4][4]={
   
   ".#.","###","..."};
char H[4][4]={
   
   ".#.","##.",".#."};
char I[4][4]={
   
   "...","###",".#."};
char J[4][4]={
   
   ".#.",".##",".#."};
char K[4][4]={
   
   ".#.","###",".#."};

int check(int x,int y){
    if(x<0||y<0||x>n*3||y>m*3||map[x][y]!='#') return 0;
    return 1;
}

void xz(int i,int j){
    if(sr[i][j]=='A') {
        for(int i=0 ; i<3 ; i++)
        for(int j=0 ; j<3 ; j++)
        tem[i][j]=A[i][j];
    }
    if(sr[i][j]=='B') {
        for(int i=0 ; i<3 ; i++)
        for(int j=0 ; j<3 ; j++)
        tem[i][j]=B[i][j];
    }
    if(sr[i][j]=='C') {
        for(int i=0 ; i<3 ; i++)
        for(int j=0 ; j<3 ; j++)
        tem[i][j]=C[i][j];
    }
    if(sr[i][j]=='D') {
        for(int i=0 ; i<3 ; i++)
        for(int j=0 ; j<3 ; j++)
        tem[i][j]=D[i][j];
    }
    if(sr[i][j]=='E') {
        for(int i=0 ; i<3 ; i++)
        for(int j=0 ; j<3 ; j++)
        tem[i][j]=E[i][j];
    }
    if(sr[i][j]=='F') {
        for(int i=0 ; i<3 ; i++)
        for(int j=0 ; j<3 ; j++)
        tem[i][j]=F[i][j];
    }
    if(sr[i][j]=='G') {
        for(int i=0 ; i<3 ; i++)
        for(int j=0 ; j<3 ; j++)
        tem[i][j]=G[i][j];
    }
    if(sr[i][j]=='H') {
        for(int i=0 ; i<3 ; i++)
        for(int j=0 ; j<3 ; j++)
        tem[i][j]=H[i][j];
    }
    if(sr[i][j]=='I') {
        for(int i=0 ; i<3 ; i++)
        for(int j=0 ; j<3 ; j++)
        tem[i][j]=I[i][j];
    }
    if(sr[i][j]=='J') {
        for(int i=0 ; i<3 ; i++)
        for(int j=0 ; j<3 ; j++)
        tem[i][j]=J[i][j];
    }
    if(sr[i][j]=='K') {
        for(int i=0 ; i<3 ; i++)
        for(int j=0 ; j<3 ; j++)
        tem[i][j]=K[i][j];
    }
}


void gz(){
    int t1,t2;
    t1=t2=0;
    int k=0;
    int t=0;
    for(int i=0 ; i<n*3 ; i++){
        for(int j=0 ; j<m*3 ; j++){
            k=i/3;
            t=j/3;
            xz(k,t);
            map[i][j]=tem[i%3][j%3];
        }
    }
}

void dfs(int x,int y){
    int i;
    for(i=0 ; i<4 ; i++){
        int nowX = x+changeX[i];
        int nowY = y+changeY[i];
        if(check(nowX,nowY)){
            map[nowX][nowY]='.';
            dfs(nowX,nowY);
        }
    }
}

int main(){
    int ans;
    while(~scanf("%d%d",&n,&m)){
        ans=0;
        if(n==-1&&m==-1) break;
        for(int i=0 ; i<n ; i++){
            for(int j=0 ; j<m ; j++){
                cin>>sr[i][j];
            }
        }
        gz();
        /*for(int i=0 ; i<n*3 ; i++){
            for(int j=0 ; j<m*3 ; j++)
            printf("%c",map[i][j]);
            puts("");
        }*/
        for(int i=0 ; i<n*3 ; i++){
            for(int j=0 ; j<m*3 ; j++)
            if(map[i][j]=='#'){
                dfs(i,j);
                ans++;
            }
        }
        printf("%d\n",ans); 
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/thesprit/article/details/51981340