一个问题纠结了好久

yahua 2011-10-09 10:30:24
本人新人 求大神


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

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

Input

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

Output

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

Sample Input


3 6
3 3 4 4 4 2
3 1 3 2 1 4
7 3 1 6 4 1
...全文
297 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
yisikaipu 2011-10-11
  • 打赏
  • 举报
回复
好主意

先添加辅助线,在地形最外围筑高墙,次外围挖深沟,灌满水,淹没整个地形

然后在沟处接上水泵抽水,使沟处的水位逐次下降,直至抽干

于是与沟连通的水被抽走,不连通的水保留下来,最后由水位与地形的高度差求得积水量

[Quote=引用 16 楼 zhao4zhong1 的回复:]

C/C++ code
//地上一大块由长M米,宽N米共M×N个小块组成的高低不平的区域,地面高度为0,每小块内部是平的,其高度为0~9米不等.
//一场大雨过后,这块区域的积水共多少立方米?
//假设水只会流到正东、正南、正西、正北相邻的且高度较低的小块里;
//而不会流到东北、东南、西北、西南相邻的且高度较低的小块里。
#include <stdio.h>
#include <time.h>……
[/Quote]
赵4老师 2011-10-11
  • 打赏
  • 举报
回复
//地上一大块由长M米,宽N米共M×N个小块组成的高低不平的区域,地面高度为0,每小块内部是平的,其高度为0~9米不等.
//一场大雨过后,这块区域的积水共多少立方米?
//假设水只会流到正东、正南、正西、正北相邻的且高度较低的小块里;
//而不会流到东北、东南、西北、西南相邻的且高度较低的小块里。
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#define M 10
#define N 10
int a[M+4][N+4];//地面高度
int w[M+4][N+4];//水面高度
int sp=0;
int xs[(M+4)*(N+4)];
int ys[(M+4)*(N+4)];
int xx,yy;
int x,y;
int i,h;
int tw;
void push(int py,int px) {
// printf("%03d %d,%d\n",sp,py,px);
ys[sp]=py;
xs[sp]=px;
if (sp<(M+4)*(N+4)-1) {
sp=sp+1;
} else {
printf("stack overflow!\n");
exit(1);
}
}
void pop(void) {
sp=sp-1;
yy=ys[sp];
xx=xs[sp];
}
int check(int cy,int cx,int ch) {
if (a[cy][cx]<=ch && w[cy][cx]>ch) return 1;
else return 0;
}
void floodfilling(int hh) {
push(1,1);
while (1) {
if (sp<=0) break;//
pop();
if (check(yy,xx,hh)) {
w[yy][xx]=hh;
if (check(yy-1,xx ,hh)) push(yy-1,xx );
if (check(yy ,xx+1,hh)) push(yy ,xx+1);
if (check(yy ,xx-1,hh)) push(yy ,xx-1);
if (check(yy+1,xx ,hh)) push(yy+1,xx );
}
}
for (y=0;y<=M+3;y++) {
for (x=0;x<=N+3;x++) {
printf("%d%d ",a[y][x],w[y][x]);
}
printf("\n");
}
for (x=0;x<=N+3;x++) printf("---");
printf("hh=%d\n",hh);
}
void main() {
//最外圈增加一圈高度9的小块
for (i=0;i<=M+3;i++) {a[i][0]=9;a[i][N+3]=9;}
for (i=0;i<=N+3;i++) {a[0][i]=9;a[M+3][i]=9;}

//次外圈增加一圈高度0的小块
for (i=1;i<=M+2;i++) {a[i][1]=0;a[i][N+2]=0;}
for (i=1;i<=N+2;i++) {a[1][i]=0;a[M+2][i]=0;}

srand(time(NULL));
for (y=2;y<=M+1;y++) {
for (x=2;x<=N+1;x++) {
a[y][x]=rand()%10;//初始地面高度
}
}

for (y=0;y<=M+3;y++) {
for (x=0;x<=N+3;x++) {
w[y][x]=9;//初始水面高度9
}
}

printf("当前每小块地面高度水面高度\n",tw);
for (y=0;y<=M+3;y++) {
for (x=0;x<=N+3;x++) {
printf("%d%d ",a[y][x],w[y][x]);
}
printf("\n");
}
for (x=0;x<=N+3;x++) printf("---");
printf("hh=9\n");

for (h=8;h>=0;h--) floodfilling(h);//检查水面高度8到0

tw=0;
for (y=2;y<=M+1;y++) {
for (x=2;x<=N+1;x++) {
tw+=(w[y][x]-a[y][x]>0)?w[y][x]-a[y][x]:0;
}
}
printf("共积水%d立方米\n",tw);
}
//当前每小块地面高度水面高度
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 09 09 09 09 09 09 09 09 09 09 09 09 99
//99 09 89 49 39 79 79 69 49 79 09 69 09 99
//99 09 19 29 59 39 39 99 09 59 49 79 09 99
//99 09 09 39 59 79 99 29 39 09 69 39 09 99
//99 09 79 59 89 59 09 39 09 49 79 49 09 99
//99 09 09 69 19 99 39 39 19 59 99 29 09 99
//99 09 29 19 39 99 79 29 39 89 79 99 09 99
//99 09 29 29 39 29 89 69 19 89 39 99 09 99
//99 09 99 99 89 79 49 79 89 69 39 09 09 99
//99 09 29 19 29 69 39 89 39 39 99 19 09 99
//99 09 79 39 19 39 19 29 19 89 69 79 09 99
//99 09 09 09 09 09 09 09 09 09 09 09 09 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=9
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 08 08 08 08 08 08 08 08 08 08 08 08 99
//99 08 88 48 38 78 78 68 48 78 08 68 08 99
//99 08 18 28 58 38 38 99 08 58 48 78 08 99
//99 08 08 38 58 78 99 28 38 08 68 38 08 99
//99 08 78 58 88 58 08 38 08 48 78 48 08 99
//99 08 08 68 18 99 38 38 18 58 99 28 08 99
//99 08 28 18 38 99 78 28 38 88 78 99 08 99
//99 08 28 28 38 28 88 68 18 88 38 99 08 99
//99 08 99 99 88 78 48 78 88 68 38 08 08 99
//99 08 28 18 28 68 38 88 38 38 99 18 08 99
//99 08 78 38 18 38 18 28 18 88 68 78 08 99
//99 08 08 08 08 08 08 08 08 08 08 08 08 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=8
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 07 07 07 07 07 07 07 07 07 07 07 07 99
//99 07 88 47 37 77 77 67 47 77 07 67 07 99
//99 07 17 27 57 37 37 99 07 57 47 77 07 99
//99 07 07 37 57 77 99 27 37 07 67 37 07 99
//99 07 77 57 88 57 07 37 07 47 77 47 07 99
//99 07 07 67 17 99 37 37 17 57 99 27 07 99
//99 07 27 17 37 99 77 27 37 88 77 99 07 99
//99 07 27 27 37 27 88 67 17 88 37 99 07 99
//99 07 99 99 88 77 47 77 88 67 37 07 07 99
//99 07 27 17 27 67 37 88 37 37 99 17 07 99
//99 07 77 37 17 37 17 27 17 88 67 77 07 99
//99 07 07 07 07 07 07 07 07 07 07 07 07 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=7
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 06 06 06 06 06 06 06 06 06 06 06 06 99
//99 06 88 46 36 77 77 66 46 77 06 66 06 99
//99 06 16 26 56 36 36 99 06 56 46 77 06 99
//99 06 06 36 56 77 99 26 36 06 66 36 06 99
//99 06 77 56 88 56 06 36 06 46 77 46 06 99
//99 06 06 66 16 99 36 36 16 56 99 26 06 99
//99 06 26 16 36 99 77 26 36 88 77 99 06 99
//99 06 26 26 36 26 88 66 16 88 36 99 06 99
//99 06 99 99 88 77 46 77 88 66 36 06 06 99
//99 06 26 16 26 66 36 88 36 36 99 16 06 99
//99 06 77 36 16 36 16 26 16 88 66 77 06 99
//99 06 06 06 06 06 06 06 06 06 06 06 06 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=6
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 05 05 05 05 05 05 05 05 05 05 05 05 99
//99 05 88 45 35 77 77 66 45 77 05 66 05 99
//99 05 15 25 55 35 35 99 05 55 45 77 05 99
//99 05 05 35 55 77 99 25 35 05 66 35 05 99
//99 05 77 55 88 55 05 35 05 45 77 45 05 99
//99 05 05 66 15 99 35 35 15 55 99 25 05 99
//99 05 25 15 35 99 77 25 35 88 77 99 05 99
//99 05 25 25 35 25 88 66 15 88 35 99 05 99
//99 05 99 99 88 77 45 77 88 66 35 05 05 99
//99 05 25 15 25 66 35 88 35 35 99 15 05 99
//99 05 77 35 15 35 15 25 15 88 66 77 05 99
//99 05 05 05 05 05 05 05 05 05 05 05 05 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=5
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 04 04 04 04 04 04 04 04 04 04 04 04 99
//99 04 88 44 34 77 77 66 44 77 04 66 04 99
//99 04 14 24 55 35 35 99 04 55 44 77 04 99
//99 04 04 34 55 77 99 24 34 04 66 34 04 99
//99 04 77 55 88 55 04 34 04 44 77 44 04 99
//99 04 04 66 14 99 34 34 14 55 99 24 04 99
//99 04 24 14 34 99 77 24 34 88 77 99 04 99
//99 04 24 24 34 24 88 66 14 88 34 99 04 99
//99 04 99 99 88 77 44 77 88 66 34 04 04 99
//99 04 24 14 24 66 34 88 34 34 99 14 04 99
//99 04 77 34 14 34 14 24 14 88 66 77 04 99
//99 04 04 04 04 04 04 04 04 04 04 04 04 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=4
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 03 03 03 03 03 03 03 03 03 03 03 03 99
//99 03 88 44 33 77 77 66 44 77 03 66 03 99
//99 03 13 23 55 35 35 99 04 55 44 77 03 99
//99 03 03 33 55 77 99 24 34 04 66 33 03 99
//99 03 77 55 88 55 04 34 04 44 77 44 03 99
//99 03 03 66 13 99 34 34 14 55 99 23 03 99
//99 03 23 13 33 99 77 24 34 88 77 99 03 99
//99 03 23 23 33 23 88 66 14 88 33 99 03 99
//99 03 99 99 88 77 44 77 88 66 33 03 03 99
//99 03 23 13 23 66 33 88 33 33 99 13 03 99
//99 03 77 33 13 33 13 23 13 88 66 77 03 99
//99 03 03 03 03 03 03 03 03 03 03 03 03 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=3
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 02 02 02 02 02 02 02 02 02 02 02 02 99
//99 02 88 44 33 77 77 66 44 77 02 66 02 99
//99 02 12 22 55 35 35 99 04 55 44 77 02 99
//99 02 02 33 55 77 99 24 34 04 66 33 02 99
//99 02 77 55 88 55 04 34 04 44 77 44 02 99
//99 02 02 66 13 99 34 34 14 55 99 22 02 99
//99 02 22 12 33 99 77 24 34 88 77 99 02 99
//99 02 22 22 33 23 88 66 14 88 33 99 02 99
//99 02 99 99 88 77 44 77 88 66 33 02 02 99
//99 02 22 12 22 66 33 88 33 33 99 12 02 99
//99 02 77 33 12 33 12 22 12 88 66 77 02 99
//99 02 02 02 02 02 02 02 02 02 02 02 02 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=2
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 01 01 01 01 01 01 01 01 01 01 01 01 99
//99 01 88 44 33 77 77 66 44 77 01 66 01 99
//99 01 11 22 55 35 35 99 04 55 44 77 01 99
//99 01 01 33 55 77 99 24 34 04 66 33 01 99
//99 01 77 55 88 55 04 34 04 44 77 44 01 99
//99 01 01 66 13 99 34 34 14 55 99 22 01 99
//99 01 22 12 33 99 77 24 34 88 77 99 01 99
//99 01 22 22 33 23 88 66 14 88 33 99 01 99
//99 01 99 99 88 77 44 77 88 66 33 01 01 99
//99 01 22 12 22 66 33 88 33 33 99 11 01 99
//99 01 77 33 11 33 11 22 11 88 66 77 01 99
//99 01 01 01 01 01 01 01 01 01 01 01 01 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=1
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//99 00 00 00 00 00 00 00 00 00 00 00 00 99
//99 00 88 44 33 77 77 66 44 77 00 66 00 99
//99 00 11 22 55 35 35 99 04 55 44 77 00 99
//99 00 00 33 55 77 99 24 34 04 66 33 00 99
//99 00 77 55 88 55 04 34 04 44 77 44 00 99
//99 00 00 66 13 99 34 34 14 55 99 22 00 99
//99 00 22 12 33 99 77 24 34 88 77 99 00 99
//99 00 22 22 33 23 88 66 14 88 33 99 00 99
//99 00 99 99 88 77 44 77 88 66 33 00 00 99
//99 00 22 12 22 66 33 88 33 33 99 11 00 99
//99 00 77 33 11 33 11 22 11 88 66 77 00 99
//99 00 00 00 00 00 00 00 00 00 00 00 00 99
//99 99 99 99 99 99 99 99 99 99 99 99 99 99
//------------------------------------------hh=0
//共积水40立方米
快乐的小菜鸟 2011-10-11
  • 打赏
  • 举报
回复
表示前来学习 没心情思考的说
huanzhile 2011-10-11
  • 打赏
  • 举报
回复
mark
yahua 2011-10-11
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 yisikaipu 的回复:]

好主意

先添加辅助线,在地形最外围筑高墙,次外围挖深沟,灌满水,淹没整个地形

然后在沟处接上水泵抽水,使沟处的水位逐次下降,直至抽干

于是与沟连通的水被抽走,不连通的水保留下来,最后由水位与地形的高度差求得积水量

引用 16 楼 zhao4zhong1 的回复:

C/C++ code
//地上一大块由长M米,宽N米共M×N个小块组成的高低不平的区域,地面高度为0,……
[/Quote]

牛逼
赵4老师 2011-10-11
  • 打赏
  • 举报
回复
[Quote=引用 17 楼 yisikaipu 的回复:]
好主意

先添加辅助线,在地形最外围筑高墙,次外围挖深沟,灌满水,淹没整个地形

然后在沟处接上水泵抽水,使沟处的水位逐次下降,直至抽干

于是与沟连通的水被抽走,不连通的水保留下来,最后由水位与地形的高度差求得积水量


引用 16 楼 zhao4zhong1 的回复:

C/C++ code
//地上一大块由长M米,宽N米共M×N个小块组成的高低不平的区域,地面高度为0……
[/Quote]
佩服!解释的很到位!很通俗易懂!
赵4老师 2011-10-10
  • 打赏
  • 举报
回复
仅供参考
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <graphics.h>
int xs[10000];
int ys[10000];
int i=0,xx,yy;
int fc,bc;
void push(int x,int y) {
xs[i]=x;
ys[i]=y;
if (i<10000-1) {
i=i+1;
} else {
printf("stack overflow!\n");
exit(1);
}
}
void pop(void) {
i=i-1;
xx=xs[i];
yy=ys[i];
}
int check(int x,int y) {
int c;

c=getpixel(x,y); /* 获取当前点的颜色 */
return ((c!=bc)&&(c!=fc));/* 如果颜色为边界色或填充色则不填充 */
}
void seedfilling(int x,int y,int fill_color,int boundary_color) {
fc=fill_color;
bc=boundary_color;
push(x,y);
while (1) {
if (i<=0) return;
pop();
if (check(xx,yy)) {
putpixel(xx, yy, 14);getch(); /* 加上这行显示当前填充状态 */

putpixel(xx, yy, fill_color); /* 画点 */

if (check(xx-1,yy )) push(xx-1,yy );
if (check(xx ,yy+1)) push(xx ,yy+1);
if (check(xx ,yy-1)) push(xx ,yy-1);
if (check(xx+1,yy )) push(xx+1,yy );
/* 去掉下面四句就是四连通 */
if (check(xx-1,yy-1)) push(xx-1,yy-1);
if (check(xx-1,yy+1)) push(xx-1,yy+1);
if (check(xx+1,yy-1)) push(xx+1,yy-1);
if (check(xx+1,yy+1)) push(xx+1,yy+1);
}
}
}
void main() {
int a,b,color;
int gdriver = DETECT, gmode, errorcode;
int poly[10];

initgraph(&gdriver, &gmode, "d:\\bc\\bgi");
a=150;
b=140;
color=4;
poly[0]=110;/* 第一个点的x坐标以及y坐标 */
poly[1]=110;
poly[2]=200;/* 第二点 */
poly[3]=105;
poly[4]=170;/* 第三点 */
poly[5]=120;
poly[6]=150;/* 第四点 */
poly[7]=170;
poly[8]=110;/* 多边形的起点与终点一样 */
poly[9]=110;
drawpoly(5,poly);/* 显示各点连接起来的多边形 */

/* 保证边界对八连通是封闭的 */
setviewport(0,1,600,300,0);
drawpoly(5,poly);/* 显示各点连接起来的多边形 */
setviewport(1,0,600,300,0);
drawpoly(5,poly);/* 显示各点连接起来的多边形 */
setviewport(1,1,600,300,0);
drawpoly(5,poly);/* 显示各点连接起来的多边形 */

/* 恢复默认viewport */
setviewport(0,0,600,300,0);

seedfilling(a,b,color,15); /* 种子填充多边形 */

getch();
closegraph();
}
赵4老师 2011-10-10
  • 打赏
  • 举报
回复
参考“种子填充算法”
yisikaipu 2011-10-10
  • 打赏
  • 举报
回复
笨办法

数据矩阵D0
334442
313214
731641

首先生成候选矩阵C0,把外围置零
000000
011110
000000

为0的位置表示肯定不可积水,为1的暂不可知
然后通过D0与C0,从外至里,检查连通,为1的位置如果与为0的位置连通,则置零,当C所有元素为零时终止

计算可能的最大的坑的面积M0,这里为4

至外向里,查找面积1个单位的坑,如果有,则填满,计算填充量V0,填充后,D0变为D1
334442
333224
731641

检查连通,C0变为C1
000000
000110
000000

M0变为M1,此处为2

如果没有找到1个单位的坑,则查找面积2个单位的坑,如果没有,则继续,直至面积为M0的坑

查找面积2个单位的坑,如果有,则填满,计算填充量V1,填充后,D1变成D2
334442
333334
731641

C1变成C2
000000
000000
000000

M1变为M2,此时为0,即C2所有元素为零

如果没有找到2个单位的坑,则查找面积3个单位的坑(如果M1>=3),如果没有,则继续,直至面积为M1的坑

最后,积水量=V0+V1+……

所以,主要的问题就是连通检查和坑的内外边界检查
KiriIsomer 2011-10-10
  • 打赏
  • 举报
回复
看完了题目,无责任猜想一下,权当发散思维.

其实不用去算坑,只要模拟下雨的情形就可以了.每次下雨往每个土地下一个单位,这样该土地的海拔(- -姑且这么叫吧)就会升高1,然后再跟周围4格做一个比较,把放不下的水剔除.这样反复下几场雨,当某场雨全部被剔除的时候,说明再也装不下了,最后把差值一减,就是这片土地的容积了.

代码就不敲了,,,费时.
灵魂制造者 2011-10-10
  • 打赏
  • 举报
回复
全体减到某一值为0 此时再算其他高度 sum下就OK了
yahua 2011-10-10
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 yisikaipu 的回复:]

顶起来
ps:这个问题只给20分实在太少
[/Quote]

不在于分 在于学习 说得好当然有加分了呀
yisikaipu 2011-10-10
  • 打赏
  • 举报
回复
没人顶?

我贴个笨算法吧,很直白,一遍一遍地刷新

改进余地很大,但都是琐碎工作

主要问题是从小到大填坑,碰到example 3的情况确实费劲


#include "stdafx.h"

#include <iostream>

using namespace std;

enum
{
NoCapacity= 0,
Capacity= 1,

EqualLeft= 2,
EqualTop= 4,
EqualRight= 8,
EqualBottom= 16,

TowardLeft= 32,
TowardTop= 64,
TowardRight= 128,
TowardBottom= 256,

Hold= 512
};

int max_element=0;
int outlet_height=0;
int vol=0;

// example 1
/*const int row=3, col=6;
int data[row][col]=
{
3,3,4,4,4,2,
3,1,3,2,1,4,
7,3,1,6,4,1,
};*/

// example 2
/*const int row=4, col=6;
int data[row][col]=
{
3,3,4,4,4,2,
3,1,3,2,1,4,
7,3,1,6,1,5,
2,2,2,2,1,7
};*/

// example 3
const int row=8, col=8;
int data[row][col]=
{
1,7,7,7,7,7,7,2,
8,6,5,4,4,5,6,9,
8,5,4,3,3,4,5,9,
9,4,3,2,2,3,4,9,
8,3,2,1,7,2,3,9,
8,4,3,2,2,3,4,9,
8,7,4,3,3,4,5,9,
2,7,7,7,7,7,7,4,
};

int candidate[row][col];

int get_max_element()
{
int temp=data[1][1];
for(int i=0;i<row-1;++i)
for(int j=0;j<col-1;++j)
if(data[i][j]>temp)
temp=data[i][j];
return temp;
}

void print()
{
cout <<"_____________________________" <<endl;
cout <<endl;

for(int i=0;i<row;++i)
{
for(int j=0;j<col;++j)
cout <<data[i][j] <<'\t';
cout <<endl;
}

cout <<endl;
cout <<"volume=" <<vol <<endl;

cout <<endl;
}

void mark_candidate(int i,int j)
{
int &d=data[i][j];
int &c=candidate[i][j];

if( (NoCapacity==candidate[i][j-1] && d>=data[i][j-1]) ||
(NoCapacity==candidate[i-1][j] && d>=data[i-1][j]) ||
(NoCapacity==candidate[i][j+1] && d>=data[i][j+1]) ||
(NoCapacity==candidate[i+1][j] && d>=data[i+1][j]) )
{
c=NoCapacity;

// flood
if(candidate[i][j-1] & (TowardRight | EqualRight) )
mark_candidate(i,j-1);
if(candidate[i-1][j] & (TowardBottom | EqualBottom) )
mark_candidate(i-1,j);
if(candidate[i][j+1] & (TowardLeft | EqualLeft) )
mark_candidate(i,j+1);
if(candidate[i+1][j] & (TowardTop | EqualTop) )
mark_candidate(i+1,j);
}
else
{
if(d>data[i][j-1])
c|=TowardLeft;
else if(d==data[i][j-1])
c|=EqualLeft;

if(d>data[i-1][j])
c|=TowardTop;
else if(d==data[i-1][j])
c|=EqualTop;

if(d>data[i][j+1])
c|=TowardRight;
else if(d==data[i][j+1])
c|=EqualRight;

if(d>data[i+1][j])
c|=TowardBottom;
else if(d==data[i+1][j])
c|=EqualBottom;
}
}

void update_candidate()
{
for(int i=1;i<row-1;++i)
for(int j=1;j<col-1;++j)
if(candidate[i][j]>0)
mark_candidate(i, j);

print();
}

void hold_one_unit(int i,int j)
{
outlet_height=data[i-1][j];
if(data[i][j-1]<outlet_height)
outlet_height=data[i][j-1];
if(data[i+1][j]<outlet_height)
outlet_height=data[i+1][j];
if(data[i][j+1]<outlet_height)
outlet_height=data[i][j+1];
}

void hold_big_region(int i,int j)
{
int &c=candidate[i][j];
c|=Hold;

int &c_neibor_left=candidate[i][j-1];
if(!(c_neibor_left & Hold) )
{
if(c_neibor_left & EqualRight)
{
hold_big_region(i,j-1);
}
else if(c_neibor_left & TowardRight || NoCapacity==c_neibor_left)
{
if(data[i][j-1]<outlet_height)
outlet_height=data[i][j-1];
}
}

int &c_neibor_top=candidate[i-1][j];
if(!(c_neibor_top& Hold) )
{
if(c_neibor_top & EqualBottom)
{
hold_big_region(i-1,j);
}
else if(c_neibor_top & TowardBottom || NoCapacity==c_neibor_top)
{
if(data[i-1][j]<outlet_height)
outlet_height=data[i-1][j];
}
}

int &c_neibor_right=candidate[i][j+1];
if(!(c_neibor_right & Hold) )
{
if(c_neibor_right & EqualLeft)
{
hold_big_region(i,j+1);
}
else if(c_neibor_right & TowardLeft || NoCapacity==c_neibor_right)
{
if(data[i][j+1]<outlet_height)
outlet_height=data[i][j+1];
}
}

int &c_neibor_bottom=candidate[i+1][j];
if(!(c_neibor_bottom & Hold) )
{
if(c_neibor_bottom & EqualTop)
{
hold_big_region(i+1,j);
}
else if(c_neibor_bottom & TowardTop || NoCapacity==c_neibor_bottom)
{
if(data[i+1][j]<outlet_height)
outlet_height=data[i+1][j];
}
}
}

void fill_data(int x,int y)
{
int &c=candidate[x][y];
int &d=data[x][y];

if(Capacity==c)
{
hold_one_unit(x,y);

vol+=outlet_height-d;
d=outlet_height;
}
else
{
hold_big_region(x,y);

int delta=outlet_height-d;

for(int i=1;i<row-1;++i)
for(int j=1;j<col-1;++j)
if(candidate[i][j] & Hold)
{
vol+=delta;
data[i][j]=outlet_height;
}
}

// clear mark
for(int i=1;i<row-1;++i)
for(int j=1;j<col-1;++j)
if(candidate[i][j]>NoCapacity)
candidate[i][j]=Capacity;

update_candidate();

// reset
outlet_height=max_element;
}

void get_min_element_coord(int &x,int&y)
{
int temp=max_element;
for(int i=1;i<row-1;++i)
for(int j=1;j<col-1;++j)
{
if(candidate[i][j]>NoCapacity && data[i][j]<temp)
{
temp=data[i][j];
x=i;
y=j;
}
}
}

void init_candidate()
{
for(int i=1;i<row-1;++i)
for(int j=1;j<col-1;++j)
candidate[i][j]=Capacity;

update_candidate();
}

bool is_finished()
{
for(int i=1;i<row-1;++i)
for(int j=1;j<col-1;++j)
if(candidate[i][j]>NoCapacity)
return false;
return true;
}


int _tmain(int argc, _TCHAR* argv[])
{
outlet_height=max_element=get_max_element();

init_candidate();

while(!is_finished() )
{
int x,y;
get_min_element_coord(x,y);

fill_data(x,y);
}

return 0;
}
yisikaipu 2011-10-10
  • 打赏
  • 举报
回复
顶起来
ps:这个问题只给20分实在太少
haoruixiang 2011-10-09
  • 打赏
  • 举报
回复
期待高手 自己明天想想
小湿哥 2011-10-09
  • 打赏
  • 举报
回复
这个建筑上可以聚合的积水的最大值。


给出 每一英寸 土地的高度,那么, 就得算出 这10000英寸的土地上一共多少个坑,把所有坑的容积加出来,也就是 积水的最大值。

难点就在于 如何 统计出这些坑。。

比如
222
212
223
这个9英寸的土地只有一个坑。。容积根据四周高度的木桶原理, 这个坑容积就是1立方英寸。

再如
33333
32223
42123
32224
33333
这个25英寸的土地上有一个稍微大一点的坑。 是 10 立方英寸。。

好吧。。现在 只求一种算法, 能计算出所有的坑。。阿门。
yisikaipu 2011-10-09
  • 打赏
  • 举报
回复
猜测Sample Output是如下矩阵所有元素的和,即2+1+2=5
000000
020120
000000
各元素表示各地块的最大积水量
[Quote=引用 2 楼 matrixcl 的回复:]
有Sample Input, 没有Sample Output吗?

这块地的周围是什么高度,0吗?
[/Quote]
yahua 2011-10-09
  • 打赏
  • 举报
回复
Sample Input
5
3 3 4 4 4 2
3 1 3 2 1 4
7 3 1 6 4 1
这些数值就是高度啊
iamnobody 2011-10-09
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 matrixcl 的回复:]
引用 1 楼 w170532934 的回复:

lz,你的结贴率不漂亮。飘过...


楼主貌似只问过一个问题,结帖率为0很正常呢。



有Sample Input, 没有Sample Output吗?

这块地的周围是什么高度,0吗?
[/Quote]

应该是0吧,不然不用算了,就无穷大。
matrixcl 2011-10-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 w170532934 的回复:]

lz,你的结贴率不漂亮。飘过...
[/Quote]

楼主貌似只问过一个问题,结帖率为0很正常呢。



有Sample Input, 没有Sample Output吗?

这块地的周围是什么高度,0吗?
加载更多回复(1)

64,654

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧