zoukankan      html  css  js  c++  java
  • SSLZYC 洛谷 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;
    } 
  • 相关阅读:
    动态SQL和PL/SQL的EXECUTE选项分析
    PL/SQL开发中动态SQL的使用方法
    windows 快捷调用
    Windows PE 工具
    面向对象(OOP)五大基本原则
    图像几何变换(geometric transformation)
    BP神经网络模型及梯度下降法
    人工神经元模型及常见激活函数
    Python: PS 滤镜--高反差保留 (High pass)
    Python: PS 滤镜--碎片特效
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/9313081.html
Copyright © 2011-2022 走看看