https://ac.nowcoder.com/acm/contest/403/A
解析:该题很明显是一道搜索题。首先我们必须明确在什么情况下会形成水洼:即当某一点的高度小于等于( <= )上下左右四个方向时,会形成水洼。
该题是要计算形成水洼的面积,那么我们的某一块最大存水量一定是四个方向上最小的高度。
- 第一次的写法:只是使用深搜去枚举每一个点,但写完发现这样写是有问题,对每一点枚举时,只是一直在对周围比较,却没有考虑离该点更远的点,这样显然时不对的
wa的代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
using namespace std;
const int maxn = 1e3+5;
const int INF = 1e9+7;
int a[maxn][maxn];
int h[maxn][maxn];
int vis[maxn][maxn];
int n, m;
int xx[] = {0, -1, 0, 1};
int yy[] = {-1, 0, 1, 0};
void dfs(int x, int y){
//printf("%d %d\n", x, y);
if(x == n && y == m){
// printf("%d %d\n", x, y);
return ;
}
if(y <= m) dfs(x, y+1);
int num = 0, mi = INF;
if(!vis[x][y]){
for(int i = 0; i < 4; i++){
int dx, dy;
dx = x + xx[i];
dy = y + yy[i];
if(dx >= 1 && dx <= n && dy >= 1 && dy <= m){
if(a[x][y] <= h[dx][dy]){
num++;
mi = min(mi, h[dx][dy]);
}
}
}
//printf("!!!!! %d %d\n", mi, num);
}
if(num == 4){
h[x][y] = mi;
}
vis[x][y] = 1;
if(x <= n) dfs(x+1, y);
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++){
scanf("%d", &a[i][j]);
h[i][j] = a[i][j];
if(i == 1 || i == n || j == 1 || j == m)
vis[i][j] = 1;
}
int ans = 0;
dfs(1, 1);
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
printf("%d ", h[i][j]);
}
printf("\n");
}
printf("%d\n", ans);
return 0;
}
/*
0 0 0 0 0 0 0 0 0 0
0 5 2 6 4 3 1 7 8 0
0 6 4 2 3 5 1 4 6 0
0 3 6 4 1 2 4 7 8 0
0 2 5 5 1 2 3 4 4 0
0 2 3 1 5 4 4 1 4 0
0 4 1 2 3 4 5 2 1 0
0 7 5 5 1 5 4 5 7 0
0 1 3 5 5 4 6 8 7 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 5 2 6 4 3 1 7 8 0
0 6 4 3 3 5 1 4 6 0
0 3 6 4 1 2 4 7 8 0
0 2 5 5 1 2 3 4 4 0
0 2 3 2 5 4 4 2 4 0
0 4 2 2 3 4 5 2 1 0
0 7 5 5 3 5 5 5 7 0
0 1 3 5 5 4 6 8 7 0
0 0 0 0 0 0 0 0 0 0
*/
- 使用已经确定的点来不断更新未确定的点,知道遍历所有的点。在这里使用堆来进行维护,可以更加方便。ac
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
const int maxn = 1e3+5;
struct Node{
int x, y, h;
bool operator < (const Node &a) const
{
return h > a.h;
}
};
priority_queue<Node>pq;
int a[maxn][maxn];
int h[maxn][maxn];
int vis[maxn][maxn];
int n, m;
int xx[] = {0, -1, 0, 1};
int yy[] = {-1, 0, 1, 0};
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
scanf("%d", &a[i][j]);
h[i][j] = a[i][j];
if(i == 1 || i == n || j ==1 || j == m){
vis[i][j] = 1;
pq.push(Node{i, j, a[i][j]});
}
}
}
while(!pq.empty()){
Node t = pq.top(); pq.pop();
int tmph = t.h;
for(int i = 0; i < 4; i++){
int dx = t.x + xx[i];
int dy = t.y + yy[i];
if(dx < 1 || dx > n || dy < 1 || dy > m || vis[dx][dy]) continue;
h[dx][dy] = max(h[dx][dy], tmph);
vis[dx][dy] = 1;
pq.push(Node{dx, dy, h[dx][dy]});
}
}
long long ans = 0;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m; j++){
//ans += (h[i][j] - a[i][j]) * 1LL;
printf("%d ", h[i][j]);
}
printf("\n");
}
printf("%lld\n", ans);
return 0;
}
/*
0 0 0 0 0 0 0 0 0 0
0 5 2 6 4 3 1 7 8 0
0 6 4 2 3 5 1 4 6 0
0 3 6 4 1 2 4 7 8 0
0 2 5 5 1 2 3 4 4 0
0 2 3 1 5 4 4 1 4 0
0 4 1 2 3 4 5 2 1 0
0 7 5 5 1 5 4 5 7 0
0 1 3 5 5 4 6 8 7 0
0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0
0 5 2 6 4 3 1 7 8 0
0 6 4 4 4 5 1 4 6 0
0 3 6 4 4 4 4 7 8 0
0 2 5 5 4 4 4 4 4 0
0 2 3 3 5 4 4 2 4 0
0 4 3 3 3 4 5 2 1 0
0 7 5 5 3 5 5 5 7 0
0 1 3 5 5 4 6 8 7 0
0 0 0 0 0 0 0 0 0 0
*/