SSL-ZYC 洛谷 P2919 守护农场

题目大意:
求一个图山丘的数量。一个山丘是指某一个方格,与之相邻的方格的海拔高度均严格小于它。当然,与它相邻的方 格可以是上下左右的那四个,也可以是对角线上相邻的四个。


思路:
今天又上洛谷打了一道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;
} 

猜你喜欢

转载自blog.csdn.net/ssl_zyc/article/details/79841452