水流

题目描述

全球气候变暖,小镇A面临水灾。于是你必须买一些泵把水抽走。泵的抽水能力可以认为是无穷大,但你必须把泵放在合适的位置,从而能使所有的水能流到泵里。小镇可以认为是N×M的矩阵。矩阵里的每个单元格都是一个“a”-“z”小写字母,该小写字母表示该格子的高度,字母大的表示该单元格比较高,反之,表示该格子高度比较低。当前单元格的水可以流到上、下、左、右四个格子,但必须满足这些格子的高度是小于或者等于当前格子的高度。现在,给你一些N×M的矩阵,你至少要买多少个泵,才能把所有格子的水都能被抽走?

输入输出格式

输入格式:

多组测试数据。

第一行,一个整数K,表示有K组测试数据。1≤K≤5;

接下来有K组测试数据,每组测试数据格式如下:

第一行,两个正数,N,M。1≤N,M≤50,表示小镇的大小;

接下来有N行,每行有M个小写字母,表示小镇的地图。

输出格式:

共K行,每行对应一组数据。至少要买多少个泵,才能把所有格子的水都能抽走。

输入输出样例

输入样例一:
2 
5 5 
ccccc
cbbbc
cbabc
cbbbc
ccccc
4 9 
cbabcbabc
cbabcbabc
cbabcbabc
cbabcbabc
输出样例一:
1
2
输入样例二:
1
11 11
ccccccccccc
caaaaaaaaac
caaaaaaaaac
caazpppzaac
caapdddpaac
caapdddpaac
caapdddpaac
caazpppzaac
caaaaaaaaac
caaaaaaaaac
ccccccccccc
输出样例二:
2

思路:每轮找最低处,进行抽水.
代码:
//程序名:新的C++程序
//作者: 

#include<iostream>
#include<fstream>
#include<algorithm>
#include<cstring>

using namespace std;
int n,a,b,e[55][55],g[55][55],smallx,smally,ans;
char f;
void scanf()
{
    memset(e,0,sizeof(e));
    cin>>a>>b;
    for(int j=1;j<=a*b;j++)
    {
        cin>>f;    
        e[(j-1)/b+1][(j-1)%b+1]=f-96;
    }
}
void getsmall()
{
    int minn=27;
    smallx=0;smally=0;
    for(int i=1;i<=a;i++)
    {
        for(int j=1;j<=b;j++)if(e[i][j]<minn&&e[i][j]!=0)minn=e[i][j],smallx=i,smally=j;
    }
}
void dfs(int w,int x)
{
    if(e[w-1][x]>=e[w][x]&&w-1>0&&!g[w-1][x]){g[w-1][x]=1;dfs(w-1,x);}
    if(e[w][x-1]>=e[w][x]&&x-1>0&&!g[w][x-1]){g[w][x-1]=1;dfs(w,x-1);}
    if(e[w+1][x]>=e[w][x]&&w+1<=a&&!g[w+1][x]){g[w+1][x]=1;dfs(w+1,x);}
    if(e[w][x+1]>=e[w][x]&&x+1<=b&&!g[w][x+1]){g[w][x+1]=1;dfs(w,x+1);}
    return;
}
void water()
{
    for(int i=1;i<=a;i++)
        for(int j=1;j<=b;j++)if(g[i][j]==1)e[i][j]=0;
    memset(g,0,sizeof(g));
}
bool check()
{
    for(int i=1;i<=a;i++)
        for(int j=1;j<=b;j++)if(e[i][j]!=0)return true;
    return false;
}
void printf1()
{
    cout<<"e:"<<endl;
    for(int i=1;i<=a;i++)
    {
        for(int j=1;j<=b;j++)cout<<e[i][j]<<" ";cout<<endl;
    }
    cout<<endl;
}
void printf2()
{
    cout<<"g:"<<endl;
    for(int i=1;i<=a;i++)
    {
        for(int j=1;j<=b;j++)cout<<g[i][j]<<" ";cout<<endl;
    }
    cout<<endl;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        scanf();
        ans=0;
        while(check())
        {
            //printf1();
            getsmall();
            //cout<<smallx<<" "<<smally<<endl;    
            g[smallx][smally]=1;            
            dfs(smallx,smally);
            water();
            //printf2();
            //printf1();
            ans++;
        }
        cout<<ans<<endl;
    }
    

    return 0;
}
 
View Code

 

posted @ 2019-04-15 13:36  背‘水’一栈  阅读(279)  评论(0编辑  收藏  举报