题目大意:

用一个数组代表群山的高度。高度大的地方代表山峰,小的地方代表山谷。山谷可以容水。假设有一天下了大雨,求群山中总共可以容纳多少水?

如图所示情况,a代表该数组,总共可以容纳5个水。

解题思路:

初步想法可以枚举每一个单位,判断是否能放水。这种做法的复杂度为O(n^2*h)其中h为数组最大值,n为数组的大小。效率较低。

进一步观察发现:由于只有山谷可以存水,假设a[i],a[j]>a[k](i<k<j),那么i,j之间的水量可以直接算出,问题降解为两个子问题:求0到i的存水量和j到n-1的存水量

代码:

#include <iostream>
#include <algorithm>
#define maxn 1000
using namespace std; int hills[maxn];
int highest[maxn][maxn];
int highone[maxn][maxn];
int stones[maxn][maxn];
int total = ;
int n; int calWater(int f, int t) {
//not yet implemented
if (f+==t)
return ;
return (t-f-)*min(hills[f], hills[t])-stones[f+][t-];
} void solve(int f, int t) {
if (f >= t)
return;
int n1, n2;
n1 = highone[f][t];
n2 = highest[f][n1-1] > highest[n1+1][n-1] ? highone[f][n1-1] : highone[n1+1][n-1];
if (n1 > n2) {
swap(n1, n2);
}
total += calWater(n1, n2);
solve(f, n1);
solve(n2, t);
} int main() {
int i;
cin >> n;
for (i = ; i < n; i++) {
cin >> hills[i];
}
for (i = ; i < n; i++) {
highest[i][i] = hills[i];
stones[i][i] = hills[i];
highone[i][i] = i;
}
int step = ;
int f,t,m;
while (step <= n) {
for (i = ; i <= n-step; i++) {
f = i;
t = i+step-;
m = (f+t)/;
highest[i][i+step-] = max(highest[i][m], highest[m+][i+step-]);
highone[i][i+step-] = highest[i][m] > highest[m+][i+step-] ? highone[i][m] : highone[m+][i+step-];
stones[i][i+step-] = stones[i][m] + stones[m+][i+step-];
}
step++;
}
solve(, n-);
cout << total << endl;
}

心得体会:

下面一行为吐槽请绕过。

{面试的时候被面试官问傻了(哭,连最简单的方法都没讲出来。唉,估计是终身遗憾了。不过下次面试应该会更轻松一些。要抓紧复习基础知识才行啊!}

这道题虽然简单但是用了分治的思想。没有想到更好的解法,希望有大神指点迷津!

更好的解法!(感谢@MchCyLh)

解题思路:见一楼评论

代码:

#include <iostream>
#include <algorithm> #define maxn 1000 using namespace std; int a[]; int main() {
int n, i;
cin >> n;
for (i = ; i < n; i++) {
cin >> a[i];
}
int l, hl, r, hr, tot = ;
l = hl = ;
r = hr = n-;
while (r-l>) {
if (a[hl] < a[hr]) {
i = ++l;
while (i < r && a[i] <= a[hl]) {
tot += a[hl]-a[i];
l++;
i++;
}
if (i != n) {
hl = i;
}
} else {
i = --r;
while (i > l && a[i] <= a[hr]) {
tot += a[hr]-a[i];
r--;
i--;
}
if (i != -) {
hr = i;
}
} }
cout << tot << endl;
}

复杂度降为O(n)www

Mountains(CVTE面试题)解题报告的更多相关文章

  1. Noip2018普及组初赛试题解题报告

    解题思路: 一.单项选择题 (答案:DDDBBAAAABABBBB) 1.除D外,其余均为输入设备. 2.除D外,其余都等于(617)10 ,D选项为(619)10. 3.1MB=1024KB=102 ...

  2. Facebook Hacker Cup 2014 Qualification Round 竞赛试题 Square Detector 解题报告

    Facebook Hacker Cup 2014 Qualification Round比赛Square Detector题的解题报告.单击这里打开题目链接(国内访问需要那个,你懂的). 原题如下: ...

  3. 北大ACM试题分类+部分解题报告链接

    转载请注明出处:優YoU http://blog.csdn.net/lyy289065406/article/details/6642573 部分解题报告添加新内容,除了原有的"大致题意&q ...

  4. CH Round #56 - 国庆节欢乐赛解题报告

    最近CH上的比赛很多,在此会全部写出解题报告,与大家交流一下解题方法与技巧. T1 魔幻森林 描述 Cortana来到了一片魔幻森林,这片森林可以被视作一个N*M的矩阵,矩阵中的每个位置上都长着一棵树 ...

  5. 二模13day1解题报告

    二模13day1解题报告 T1.发射站(station) N个发射站,每个发射站有高度hi,发射信号强度vi,每个发射站的信号只会被左和右第一个比他高的收到.现在求收到信号最强的发射站. 我用了时间复 ...

  6. BZOJ 1051 最受欢迎的牛 解题报告

    题目直接摆在这里! 1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 4438  Solved: 2353[S ...

  7. 习题:codevs 2822 爱在心中 解题报告

    这次的解题报告是有关tarjan算法的一道思维量比较大的题目(真的是原创文章,希望管理员不要再把文章移出首页). 这道题蒟蒻以前做过,但是今天由于要复习tarjan算法,于是就看到codevs分类强联 ...

  8. 习题:codevs 1035 火车停留解题报告

    本蒟蒻又来写解题报告了.这次的题目是codevs 1035 火车停留. 题目大意就是给m个火车的到达时间.停留时间和车载货物的价值,车站有n个车道,而火车停留一次车站就会从车载货物价值中获得1%的利润 ...

  9. 习题: codevs 2492 上帝造题的七分钟2 解题报告

    这道题是受到大犇MagHSK的启发我才得以想出来的,蒟蒻觉得自己的代码跟MagHSK大犇的代码完全比不上,所以这里蒟蒻就套用了MagHSK大犇的代码(大家可以关注下我的博客,友情链接就是大犇MagHS ...

随机推荐

  1. javascript面向对象(三):非构造函数的继承

    本文来自阮一峰 这个系列的第一部分介绍了"封装",第二部分介绍了使用构造函数实现"继承". 今天是最后一个部分,介绍不使用构造函数实现"继承" ...

  2. spark 2.0 Vector toBreeze

    def toBreeze( _v : Vector ) : BZV[Double] = { _v match { case x : org.apache.spark.mllib.linalg.Dens ...

  3. ThinkPHP 错误: Undefined class constant 'MYSQL_ATTR_INIT_COMMAND'

    在配置了ThinkPHP 的数据库配置信息后,在实例化Model(),调用相关方法时候 出现错误,改进如下方式后解决: 找到php.ini 的文件,打开扩展  php_pdo_mysql.dll ,然 ...

  4. Intellij如何设置编译后自动重新加载class文件?

    前段时间突然发现Intellij不能自动重新加载类了,每次编译后都要重新启动项目,才能显示更新效果,后来网上查询Intellij下如何配置热部署,都说是要配置构件,然后在web容器的编辑页面选择upd ...

  5. Docker对普通开发者的用处(转)

    有些开发者可能还是不明白 Docker 对自己到底有多大的用处,因此翻译 Docker 个人用例 这篇文章中来介绍 Docker 在普通开发者开发过程中的用例. Docker 如今赢得了许多关注,很多 ...

  6. Hibernate主键生成策略(转)

    1.自动增长identity 适用于MySQL.DB2.MS SQL  Server,采用数据库生成的主键,用于为long.short.int类型生成唯一标识 使用SQL Server 和 MySQL ...

  7. python类型转换

    1.数字转字符串 str(42) == "42" 2.字符串转数字 int("42") == 42 3.字符转ascii码 ord("a") ...

  8. select case巧用 oracle

    在做报表的时候,经常会用到分段统计数据,这时候,case就比较有用了: 小例子: SELECT   sh.dc_code, g.bg_code,                   TO_CHAR ( ...

  9. JetBrains注册码计算(IntelliJ IDEA 15.0注册码激活)

    安装前修改时间为2099年等很多年后的时间点,安装后选择免费试用30天,然后退出idea,把时间修改回来,这样就可以成功注册了 如果之前使用过授权服务器等激活方式,不弹出试用界面,请到C:\Users ...

  10. ajax的使用:(ajaxReturn[ajax的返回方法]),(eval返回字符串);分页;第三方类(page.class.php)如何载入;自动加载函数库(functions);session如何防止跳过登录访问(构造函数说明)

    一.ajax例子:ajaxReturn("ok","eval")->thinkphp中ajax的返回值的方法,返回参数为ok,返回类型为eval(字符串) ...