【poi1999】【cogs239】【积水】【堆】【灌水法】【贪心】

原创 2015年07月10日 21:31:58

问题描述

有这样一块土地,它可以被划分N*M个正方形小块,每块面积是一平方英寸,第i行第j列的小块可以表示成P(i,j)。这块土地高低不平,每一小块地P(i,j)都有自己的高度H(i,j)(单位是英寸)。

一场倾盆大雨后,由于这块地地势高低不同,许多低洼地方都积存了不少降水。假如你已经知道这块土地的详细信息,你能求出它最多能积存多少立方英寸的降水么?

输入格式

输入文件的第一行是两个正整数n和m,1<=n<=100,1<=m<=100,表示土地的尺寸。下面n行,每行m个整数(1..10000);第j行第i个数表示第j行第i列立方体的高。

输出格式

输出文件只有一个数,表示在这个建筑上可以聚合的积水的最大值

输入输出样例

输入

3 6
3 3 4 4 4 2
3 1 3 2 1 4
7 3 1 6 4 1

输出

5

下图是其方案:

Image:Wod.png

题解:按高度建一个小根堆,一开始把所有边界上的点入堆,从中取出高度最小的点,从该点开始floodfill,如果碰到比他高的点,就把那个点入堆,如果碰到比他低或相等的点,将高度差累加进答案,然后从那个点继续floodfill。重复以上过程直到堆空。

#include<iostream>
#include<cstdio>
#include<queue>
using namespace std;
struct use{
	int x,y,h;
};
bool operator<(use x,use y){return x.h<y.h;}  
priority_queue<use>q;  
int map[101][101],dx[5],dy[5],n,m,ans;
bool f[101][101],ff[101][101];
inline int in(){
    char c=getchar();
    int x=0;
    while(c<'0'||c>'9')c=getchar();
    for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';
    return x;
}
inline void floodfill(int x,int y,int hh)
{
	//cout<<x<<' '<<y<<' '<<hh<<endl;
	for (int i=1;i<=4;i++)
	  {
	    int xx,yy;
	    xx=x+dx[i];yy=y+dy[i];
	    if (xx>0&&xx<=n&&yy>0&&yy<=m&&!f[xx][yy])
	      {
	        if (map[xx][yy]<=-hh) {ans+=-hh-map[xx][yy];f[xx][yy]=true;floodfill(xx,yy,hh);}
	         else 
	          {
	             if (!ff[xx][yy])
				 {
				  use a;
	              a.x=xx;a.y=yy;a.h=-map[xx][yy];q.push(a);ff[xx][yy]=true;
	             }
			  }
	      }
	  }
}
int main()
{
    freopen("wod.in","r",stdin);
    freopen("wod.out","w",stdout);
	n=in();m=in();
    dx[1]=1;dx[2]=0;dx[3]=-1;dx[4]=0;
    dy[1]=0;dy[2]=1;dy[3]=0;dy[4]=-1;
	for (int i=1;i<=n;i++)
      for (int j=1;j<=m;j++)
        {
           map[i][j]=in();
           if (i==1||i==n||j==1||j==m)
             {
                use a;
                a.x=i;a.y=j;a.h=-map[i][j];
                q.push(a);
                ff[i][j]=true;
             }
        }
    while (!q.empty())
     {
	   use a;
       a=q.top();q.pop();
       if (!f[a.x][a.y]){f[a.x][a.y]=true;floodfill(a.x,a.y,a.h);}
     }
    cout<<ans;
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

2017 Nuist ACM 集训计划

Nuist ACM集训队 训练计划一、训练目的提高同学们的算法水平,提升南信大在ACM ICPC竞赛中的地位。二、集训内容现阶段我们的集训内容以 USACO 的题目 和《挑战程序设计竞赛》中推荐的PO...
  • yoer77
  • yoer77
  • 2017年05月23日 22:48
  • 753

acm 贪心总结

⑴ 有一个以最优方式来解决的问题。为了构造问题的解决方案,有一个候选的对象的集合:比如不同面值的硬币。 ⑵ 随着算法的进行,将积累起其它两个集合:一个包含已经被考虑过并被选出的候选对象,另一个包含已...
  • ljtlyy
  • ljtlyy
  • 2016年03月31日 20:35
  • 159

2016.4 半期 堆+贪心 【UASCO 2009 OPEN GOLD-2】工作安排

nkoj 1349 Description Farmer John 有太多的工作要做啊!!!!!!!!为了让农场高效运转,他必须靠他的工作赚钱,每项工作花一个单位时间。  他的工作日从0时刻开始,有...
  • INCINCIBLE
  • INCINCIBLE
  • 2016年04月21日 15:08
  • 283

手写堆

#include using namespace std; const int MAX_N = 1e3 + 10; struct Heap { int heap[MAX_N]; in...
  • yp_2013
  • yp_2013
  • 2016年06月22日 10:41
  • 604

noip2013 积木大赛 (贪心)

P1844积木大赛 Accepted 标签:NOIP提高组2013 描述 春春幼儿园举办了一年一度的“积木大赛”。今年比赛的内容是搭建一座宽度为 n 的大厦,大厦可以看...
  • yuyanggo
  • yuyanggo
  • 2015年10月30日 15:50
  • 927

Dijkstra+堆优化模板 (手写堆简单易懂)

#include #include #define MAXN 2510 #define INF 1000000000 using namespace std; int q[MAXN*2],pos[MA...
  • WhiStLenA
  • WhiStLenA
  • 2016年11月15日 15:45
  • 586

论坛灌水机(续)

 大概在2年零两个月前,我写过一个论坛灌水机,前几天,因为朋友要网络投票,又拿出来用了一次,改了下配置文件,又可以当投票机用了。由于工作的关系,现在在UNIX上做开发了,我尝试了用UNIX重写了一个投...
  • oyd
  • oyd
  • 2006年11月21日 00:12
  • 9613

党课心得二(杂谈)

周日上午在一教401教师,校党委宣传部部长王金海老师为我们讲解“十八届五中全会”的内容。    王老师给人的第一感觉是讲话底气很足,声音宏亮,和下午的江水法老师说话声音对比很鲜明,或许也和他常年从事...
  • k183000860
  • k183000860
  • 2016年04月24日 21:04
  • 219

漫水算法原理及其实现

一 漫水填充算法描述     1..1 、种子填充算法          种子填充算法是从多边形区域内部的一点开始,由此出发找到区域内的所有像素。          种子填充算法采用...
  • fengxianghui01
  • fengxianghui01
  • 2017年04月15日 21:39
  • 603

有趣的积水问题(Twitter编程面试题)

以下内容来自转载: Twitter面试题:水沟积水问题 问题描述:“看下面这个图片” “在这个图片里我们有不同高度的墙。这个图片由一个整数数组所代表,数组中每个数是墙的高度。上边的图可以表...
  • qq_33765907
  • qq_33765907
  • 2016年04月14日 20:41
  • 547
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【poi1999】【cogs239】【积水】【堆】【灌水法】【贪心】
举报原因:
原因补充:

(最多只允许输入30个字)