题目大意:
求一个图山丘的数量。一个山丘是指某一个方格,与之相邻的方格的海拔高度均严格小于它。当然,与它相邻的方 格可以是上下左右的那四个,也可以是对角线上相邻的四个。
思路:
今天又上洛谷打了一道DFS的题目。。。
这道题应该是细胞问题啊,找石油啊,数池塘啊的进化版。思路以及方法和它们都差不多,但是搜索的方法有些不同。
其他三道题是可以按顺序枚举每个点的,而这道题要从最高点开始,枚举到最低点,就有点“随机”的感觉。
除此之外,从高到低枚举要用结构体,不然TLE几个点。
代码:
1.不用结构体,80分
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int inf=9999999;
int n,m,h[10001],a[1001][1001],sum,k,x,y,ans,ok;
void dfs(int x,int y)
{
sum++;
h[a[x][y]]--;
int o=a[x][y];
a[x][y]=inf;
if (o>=a[x-1][y-1]) dfs(x-1,y-1);
if (o>=a[x-1][y]) dfs(x-1,y);
if (o>=a[x-1][y+1]) dfs(x-1,y+1);
if (o>=a[x][y-1]) dfs(x,y-1);
if (o>=a[x][y+1]) dfs(x,y+1);
if (o>=a[x+1][y-1]) dfs(x+1,y-1);
if (o>=a[x+1][y]) dfs(x+1,y);
if (o>=a[x+1][y+1]) dfs(x+1,y+1);
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=0;i<=m+1;i++) a[0][i]=a[n+1][i]=inf;
for (int i=0;i<=n+1;i++) a[i][0]=a[i][m+1]=inf;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
scanf("%d",&a[i][j]);
h[a[i][j]]++;
if (a[i][j]>k)
{
k=a[i][j];
x=i;
y=j;
}
}
while (sum<n*m)
{
ok=0;
dfs(x,y);
ans++;
if (sum==n*m) break;
while (h[k]==0) k--;
for (int i=1;i<=n&&ok==0;i++)
for (int j=1;j<=m;j++)
if (a[i][j]==k)
{
x=i;
y=j;
ok=1;
break;
}
}
printf("%d\n",ans);
return 0;
}
2.结构体,AC
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int inf=9999999;
int n,m,a[1001][1001],sum,k,x,y,ans,ok,l;
struct N //结构体
{
int x,y,h; //分别表示横坐标,纵坐标和高度
}f[10000001];
bool cmp(N x,N y)
{
return x.h>y.h;
}
void dfs(int x,int y)
{
sum++; //记录已经搜索过的点的个数
int o=a[x][y];
a[x][y]=inf; //标记
if (o>=a[x-1][y-1]) dfs(x-1,y-1);
if (o>=a[x-1][y]) dfs(x-1,y);
if (o>=a[x-1][y+1]) dfs(x-1,y+1);
if (o>=a[x][y-1]) dfs(x,y-1);
if (o>=a[x][y+1]) dfs(x,y+1);
if (o>=a[x+1][y-1]) dfs(x+1,y-1);
if (o>=a[x+1][y]) dfs(x+1,y);
if (o>=a[x+1][y+1]) dfs(x+1,y+1); //向8个方向搜索(for语句也可以)
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=0;i<=m+1;i++) a[0][i]=a[n+1][i]=inf;
for (int i=0;i<=n+1;i++) a[i][0]=a[i][m+1]=inf; //初始化,将改图边界的所有点都标记(防止越界)
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
{
l++;
scanf("%d",&a[i][j]);
f[l].h=a[i][j];
f[l].x=i;
f[l].y=j;
}
l=0;
sort(f+1,f+1+n*m,cmp); //快排
while (sum<n*m)
{
ans++; //记录山峰个数
while (a[f[l].x][f[l].y]==inf) l++;
dfs(f[l].x,f[l].y);
}
printf("%d\n",ans);
return 0;
}