【JZOJ】1341. water(水流)

题目大意 你必须买一些泵把水抽走。泵的抽水能力可以认为是无穷大,但你必须把泵放在合适的位置,小镇可以认为是N * M的矩阵。矩阵里的每个单元格都是一个‘a’- ‘z’小写字母,该小写字母表示该格子的高度,字母大的表示该单元格比较高,反之,表示该格子高度比较低。当前单元格的水可以流到上、下、左、右四个格子,一共要多少个泵?

这道题目可以用搜索做,为什么呢?

我们可以把小镇当做一个地图来看*mn**的地图,我知道每一个格子的深度,我要找最深的那一个,只能用上下左右来进行寻找

我们就可以转化成,在一张n*m(个格子组成的)大小的地图中,找到最大的那一个格子。

于是我们便可以想到用dfs,但并不完全是dfs

我们可以用一个数组来保存状态,s[i][j],如果这一个格子没有被标记过(也就是没有走过),并且这个格子在我正张地图的范围之内,便可以执行我们的dfs函数 最后输出ans

在dfs函数中我们先用s[i][j]来保存当前状态, 之后再进行搜索,我们有上下左右四个方向进行移动,循环来保存新的x,y;之后再进行判断新的x与y是否再范围之内,我们的s数组是否标记过,再是判断当前位置是否离开了原位(很重要必须得离开原位),之后再将我们得到得新的x与y,进行调用,再做标记(记得要清零,标记放循环前)

其实这dfs很像递归但又像dfs。。。。

这样这道题就完成了;

上代码吧

 1 include<iostream>
 2 include<cstdio>
 3 include<cmath>
 4 include<algorithm>
 5 include<cstring>
 6 using namespace std;
 7 
 8 const int maxn= 53;
 9 
10 int N, M;
11 
12 char maze[maxn][maxn];
13 
14 char s[maxn][maxn];
15 
16 int xi[] = {0, 0, -1, 1};
17 
18 int yi[] = {1, -1, 0, 0};
19 
20 void dfs(int x, int y) { s[x][y]=1; for(int i=0; i<4; i++) {
21 
22     int nx=x+xi[i]; 
23 
24     int ny=y+yi[i]; 
25 
26     if(nx>=0&&nx<N&& ny>=0&&ny<M&&s[nx][ny]==0&&maze[nx[ny]>=maze[x][y]) {
27         dfs(nx,ny);
28 
29     }
30 
31 }
32 }//一个很简单的搜索
33 
34 int main() {
35 
36 int t=0;
37 
38 cin>>t;
39 
40 while(t--) {
41 
42     cin>>N>>M;
43 
44     for(int i=0;i<N;i++) {
45 
46         cin>>maze[i];
47 
48     }
49 
50     memset(s,0,sizeof(s));
51 
52     int ans=0;
53 
54     for(char c='a';c<='z';c++) {
55 
56         for(int i = 0; i < N; i++) {
57 
58             for(int j = 0; j < M; j++) {
59 
60                 if(s[i][j] == 0 && maze[i][j] == c){
61 
62                     dfs(i, j);
63 
64                     ans++;
65 
66                 }
67 
68             }
69 
70         }
71 
72     }
73 
74     cout<<ans<<endl;
75     return 0;
76 }
原文地址:https://www.cnblogs.com/WestJackson/p/11343622.html