zoukankan      html  css  js  c++  java
  • water_堆优化+类dijkstra思想

    第一眼,每个格子取决于和他相临的格子,直接枚举O(nm),这么水?!!

    第二眼,没那么简单,要找到类似水池的东西,这个池子的边界高度的min才是此格子的高度。为了保证时间复杂度,希望能尽量找到一个格子能被覆盖的最大池子,这样能尽可能地覆盖到别的格子,能近似到一次遍历就出来了,基本O(nm)。

    然后。。。发现根本不能找到最大的池子,我的暴力是一层层把小的抬高,O(n^2m^2),QAQ

    考虑一个模拟,一格水掉到一个比较高的地上,一定会流到它能流到的最低的地方,这个最低的地方是一个坑,它一定是在类中心位置,也就是说水在一个边界向内流,我们可以不短缩小边界来更新出每个点+积水的高度。维护一个堆,取出最小的,因为一个水池的最终高度是边界高度的最小值。

    懵懂。。。

     1 #include<bits/stdc++.h>
     2 #define MAXN 310
     3 using namespace std;
     4 inline int maxn(int a,int b){return a>b?a:b; }
     5 inline int minn(int a,int b){return a<b?a:b; }
     6 int n,m;
     7 int ht[MAXN][MAXN];
     8 int zui[MAXN][MAXN];
     9 int wtr[MAXN][MAXN];
    10 struct node{
    11     int x,y;
    12     friend bool operator <(const node &a,const node &b){
    13         return zui[a.x][a.y]>zui[b.x][b.y];
    14     }
    15 };
    16 bool vis[MAXN][MAXN];
    17 priority_queue<node >dd;
    18 int fx[4][2];
    19 int main(){
    20     //freopen("da.in","r",stdin);
    21     fx[0][0]=0;fx[0][1]=1;
    22     fx[1][0]=0;fx[1][1]=-1;
    23     fx[2][0]=1;fx[2][1]=0;
    24     fx[3][0]=-1;fx[3][1]=0;
    25     scanf("%d%d",&n,&m);
    26     node tt;
    27     for(int i=1;i<=n;++i)
    28         for(int j=1;j<=m;++j){
    29             scanf("%d",&ht[i][j]);
    30             if(ht[i][j]<0)zui[i][j]=0;
    31             else zui[i][j]=ht[i][j];
    32         }
    33     for(int i=1;i<=n;++i)
    34         dd.push((node){i,0}),dd.push((node){i,m+1});
    35     for(int j=1;j<=m;++j)
    36         dd.push((node){0,j}),dd.push((node){n+1,j});
    37     int x,y;
    38     while(!dd.empty()){
    39         node ltop=dd.top();dd.pop();
    40         if(vis[x=ltop.x][y=ltop.y])continue;
    41         vis[x][y]=1;
    42         int ti,tj;
    43         for(int k=0;k<4;++k){
    44             ti=x+fx[k][0];tj=y+fx[k][1];
    45             if(vis[ti][tj])continue;
    46             if(ti<1||ti>n)continue;
    47             if(tj<1||tj>m)continue;
    48             if(zui[ti][tj]<zui[x][y])zui[ti][tj]=zui[x][y];
    49             dd.push((node){ti,tj});
    50         }
    51     }
    52     for(int i=1;i<=n;++i){
    53         for(int j=1;j<=m;++j)
    54             printf("%d ",zui[i][j]-ht[i][j]);
    55         puts("");    
    56     }
    57 }
    View Code

     

  • 相关阅读:
    OS X EI Capitan 安装mysql-5.7.9
    CAS SSO
    单点登录SSO
    videojs 视频开发API
    NodeJS无所不能:细数10个令人惊讶的NodeJS开源项目
    程序员使用Node的十个技巧
    pdf 回退快捷键
    公式神器 Mathpix Snip 比mathtype快
    AI studio 尝试
    tmux 使用
  • 原文地址:https://www.cnblogs.com/2018hzoicyf/p/11367292.html
Copyright © 2011-2022 走看看