poj 2227 & usaco 2005 月赛 The Wedding Juicer 题解

转载请注明:http://blog.csdn.net/jiangshibiao/article/details/24132503

【原题】

The Wedding Juicer

Time Limit: 2000MS

 

Memory Limit: 65536K

Total Submissions: 2953

 

Accepted: 1306

Description

Farmer John's cowshave taken a side job designing interesting punch-bowl designs. The designs arecreated as follows:

* A flat board of size W cm x H cm is procured (3 <= W<= 300, 3 <= H <= 300)
* On every 1 cm x 1 cm square of the board, a 1 cm x 1 cm block is placed. Thisblock has some integer height B (1 <= B <= 1,000,000,000)


The blocks are all glued together carefully so that punch will not drainthrough them. They are glued so well, in fact, that the corner blocks reallydon't matter!

FJ's cows can never figure out, however, just how much punch their bowl designswill hold. Presuming the bowl is freestanding (i.e., no special walls aroundthe bowl), calculate how much juice the bowl can hold. Some juice bowls, of course,leak out all the juice on the edges and will hold 0.

Input

* Line 1: Two space-separated integers, W and H

* Lines 2..H+1: Line i+1 contains row i of bowl heights: W space-separatedintegers

each of whichrepresents the height B of a square in the bowl. The first integer is theheight of column 1, the second integers is the height of column 2, and so on.

Output

* Line 1: A singleinteger that is the number of cc's the described bowl will hold.

SampleInput

4 5

5 8 7 7

5 2 1 5

7 1 7 1

8 9 6 9

9 8 9 9

SampleOutput

12

Hint

OUTPUT DETAILS:

Fill-up the two squares of height 1 to height 5, for 4 cc for each square. Fillthe square of height 2 to height 5, for 3 cc of joice. Fill the square ofheight 6 to height 7 for 1 cc of juice. 2*4 + 3 + 1 = 12.

Source

USACO 2005 January Gold

【题意】给定N*M的一个矩阵表示某一格的高度,求最多能放多少单位的水。自然,水会漫延。

【分析】这道题出的挺好。我觉得这不是考验代码能力(P党就无视吧),重在思维。(哇哈哈,其实我也是看题解的)原来的思想是二分枚举水量或高度,但是发现行不通。于是我自然的想到了bfs,,而且想到从边界向中间bfs。但是究竟该怎么控制呢?主要是有一种情况难以考虑:假设边界的最低点是5,但是中间有一个凸起,中间一圈都是7,那么中间的中间最多可以盛7单位。我们可以先把边界上的点全都加入优先队列,同时维护一个小根堆。整个堆的意义是:已堆中元素为边界去盛水。然后我们找到堆首元素并向四个方向拓展。

①如果某个点比当前的点高,那么可以把他也加入优先队列中。

②如果某个点比当前的点低,那么我就可以多盛(h-h')单位的水(两个高度差)。为什么呢?因为我当前堆首已经满足是整个边界中的最小值了;这样一点水不可能从任何其他边界出去。更新答案后,我们再把拓展出去的点的高度标为当前的高度h并加入优先队列(因为这个点以后可能还能盛水)。

直到队列为空,我们已经拓展了所有可能的点了。

【代码】

#include<cstdio>
#include<queue>
using namespace std;
struct arr
{
  int x,y,h;
  friend bool operator < (const arr &a,const arr &b)
  {
    return  a.h>b.h;
  }
}temp;
const int dx[4]={0,0,-1,1};const int dy[4]={1,-1,0,0};
priority_queue<arr>q;
int n,m,i,j,x,y,xx,yy,ans,a[305][305];
bool visit[305][305];
int main()
{
  scanf("%d%d",&m,&n);
  for (i=1;i<=n;i++)
    for (j=1;j<=m;j++)
      scanf("%d",&a[i][j]);
  for (i=1;i<=m;i++)
    q.push((arr){1,i,a[1][i]}),q.push((arr){n,i,a[n][i]}),visit[1][i]=visit[n][i]=true;
  for (i=2;i<n;i++)
    q.push((arr){i,1,a[i][1]}),q.push((arr){i,m,a[i][m]}),visit[i][1]=visit[i][m]=true;
  while (!q.empty())
  {
    temp=q.top();q.pop();x=temp.x;y=temp.y;
    for (i=0;i<=3;i++)
    {
      xx=x+dx[i];yy=y+dy[i];
      if (xx<1||xx>n||yy<1||yy>m||visit[xx][yy]) continue;
      visit[xx][yy]=true;
      if (a[xx][yy]>=temp.h) q.push((arr){xx,yy,a[xx][yy]});
      else ans+=temp.h-a[xx][yy],q.push((arr){xx,yy,temp.h});
    }
  }
  printf("%d",ans);
  return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值