洛谷 P1318 积水面积

2 篇文章 0 订阅
1 篇文章 0 订阅

题目描述

一组正整数,分别表示由正方体迭起的柱子的高度。若某高度值为x,表示由x个正立方的方块迭起(如下图,0<=x<=5000)。找出所有可能积水的地方(图中蓝色部分),统计它们可能积水的面积总和(计算的是图中的横截面积。一个立方体的位置,为一个单位面积)。

如图:柱子高度变化为 0 1 0 2 1 2 0 0 2 0

图中蓝色部分为积水面积,共有6个单位面积积水。

输入输出格式

输入格式:

两行,第一行n,表示有n个数(3<=n<=10000)。第2行连续n个数表示依次由正方体迭起的高度,保证首尾为0。

输出格式:

一个数,可能积水的面积。

输入输出样例

输入样例#1:
10
0 1 0 2 1 2 0 0 2 0

输出样例#1:
6


解题思路:

  1. 找出最高的一根柱子,从最高的一行起,一行一行向下扫描,每行扫描一遍找出最左边的一根和最右边的一根,他们之间每一个没有柱子的地方贡献一个面积的积水(好像没毛病),然后把每行答案加起来,就得到总的可能积水面积了
  2. 维护前缀最大值fro[i]和后缀最大值beh[i],对每一列对面积的贡献为h[i]-min(fro[i],beh[i]),然后从左到右,对每一列都有ans+=h[i]-min(fro[i],beh[i])(这不是显然的吗)
  3. 维护一个单调栈,还没搞懂
  4. 以上思路源码https://www.luogu.org/wiki/show?name=%E9%A2%98%E8%A7%A3+P1318
  5. 自己的思路:对所有h[i],在记录了原本位置的情况下对高度进行排序,然后枚举:对第一高的和第二高的(一样高也可以)之间所有列统计答案,标记已统计过(因为后面不能重复计算这一列,降序排序保证了越靠前计算获得水位越高),对第二高和第三高之间区间执行相同操作,对第三高和第四高区间之间执行相同操作……,第n-1高和第n高(最矮)之间区间执行相同操作,最后输出答案,ac
源码(自己思路5):
#include<cstdio>
#include<algorithm>
using namespace std;
struct data{
	int high;
	int num;
}d[100100];
int n;
bool vis[100100]={0};
int h[100100]={0};
int ans=0;
int cmp(const data & a,const data & b)
{
	return a.high>b.high;//cmp函数等于的情况要么特判,要么不管,不然re(a.high>=b.high),我不知道为什么,有知道的大牛是否能告知呢
}
int main()
{
	scanf("%d",&n);
	for(int i=0;i<n;i++)
	{
		scanf("%d",h+i);
		d[i].high=h[i];
		d[i].num=i;
	}
	sort(d,d+n,cmp);
	for(int i=0;i<n-1;i++)
	{
		int left = min(d[i].num,d[i+1].num);
		int right= max(d[i].num,d[i+1].num);//找到待修改区间的左右端点,端点处不用算,贡献面积为0
		int hh=min(h[right],h[left]);//液面高度
		vis[right]=vis[left]=true;
		for(left+=1;left<right;left++)
		{
			if(!vis[left])
			{
				vis[left]=true;
				ans+=hh-h[left];
			}
		}
	}
	printf("%d",ans);
	return 0;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Java编程中,处理台阶积水问题是一个常见的任务。台阶积水指的是台阶之间形成的坑洼,当台阶上积水超过台阶高度时,就会出现积水问题。解决台阶积水问题,可以利用Java的数据结构和算法来实现。 一种常见的解决方法是使用双指针法。首先,我们定义两个指针,分别指向台阶的左边和右边。然后,通过比较指针所指向的两个位置的高度,确定哪一侧的指针应该向中间移动。当遇到比当前最高高度低的台阶时,积水就会产生。我们可以根据这个规则来计算积水的数量。 另一种解决方案是利用动态规划。我们可以定义一个数组,存储每个台阶上方的最高高度。从左往右遍历台阶,更新每个位置的最高高度。然后从右往左遍历台阶,计算每个位置的积水量。最后将所有位置的积水量累加起来,就可以得到总的积水量。 除了这些方法外,还可以利用栈数据结构来解决。遍历台阶,将遇到的台阶高度入栈。如果遇到比栈顶高度小的台阶,说明可能会有积水产生,此时可以弹出栈顶元素,计算积水量,并继续比较下一个栈顶元素。遍历完台阶后,栈中剩下的元素也是可能会有积水产生的位置,可以继续计算积水量。 总之,无论是双指针法、动态规划还是利用栈,Java语言都提供了丰富的数据结构和算法库,可以帮助我们解决台阶积水的问题。具体使用哪种方法,可以根据实际情况和需求选择最适合的方法。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值