题目链接详见SCNU 2015新生网络赛 1006. 3D打印 。出题思路来自codevs 3288. 积木大赛,属于模拟题。
 
      首先我们把“选择从第L部分到第R部分”理解为“选择一段连续的部分”,OK,基本题意为:给定N个部件的高度,每次可以给连续的一段增加高度$1$,问至少需要几次增加高度的操作?
 
      不少人认为,直接模拟这个操作,循环给它$+1$,数加几次能达到要求高度就可以了。但很可惜这是会超时TLE哒。我们考虑极端情况,总共有$10^{5}$个部分,高度$h_{i}$是$0$和$10^{5}$相间的,这样总共需要$\frac {10^{5}} {2} \times 10^{5} = 5 \times 10^{9}$次操作,复杂度为$O(NH)$,也就是说很可能一些同学的做法,会要进行$5 \times 10^{9}$次的循环,运行结果同样也是$5 \times 10^{9}$,不但超时,而且还超了$int$整型的范围。当然良心出题人并没有把这组数据放进去,数据做了奇怪的限定能保证结果不超过$int$,否则你应该需要拿long long__int64来存放结果(32位机下$int$和$long$都是$4$字节,一样的范围)。
 
      那怎么办呢?我们可以发现,如果$h_{i} > h_{i-1}$,那么总操作次数应要加上$h_{i} - h_{i-1}$,因为假定我在到达前面高度为$h_{i-1}$的部分的时候,已经总共操作了$t_{1}$次,如果当前部分比前面的还高,那么这个部分的下面$h_{i-1}$的高度已经被前面的操作完成了(尽量选择连续的一段增加高度),于是这里我只剩下了$t_{2} = h_{i} - h_{i-1}$的高度未完成。如果$h_{i} \leq h_{i-1}$,则前面的操作肯定也把这部分顺便完成了,因此不需要再次计算。由于每次只需要比较$h_{i}$和$h_{i-1}$的大小关系,前面比较过的与后面的无关,所以只需要一个循环把数组遍历一次就可以了,复杂度为$O(N)$。
 
      代码如下(我是在读入的时候就完成判断,因此不需要数组保存了):
 #include <stdio.h>

 int main() {
int T, N;
scanf("%d", &T);
while(T--) {
int t = , x;
long long res = ;
scanf("%d", &N);
for(int i=; i<N; i++) {
scanf("%d", &x);
if(x>t) res += x-t;
t = x;
}
printf("%I64d\n", res);
}
return ;
}
 
      在提交的代码中发现有同学想到了另一种方法,即寻找极大极小值的做法,复杂度同样为$O(N)$。比如我先找到一个极小值$rmin$,往后面找到一个极大值$rmax$,这样总次数只需加上$rmax - rmin$即可,因为极小值前面的部分已经计算过了,只需要考虑极小值到极大值之间的操作次数就好了。当然一开始时极小值为$0$,遍历结束后也要注意加上还没计算的部分,略微麻烦点,留给大家思考。
 
      附:数据生成程序如下:
 #include <stdio.h>
#include <random>
using namespace std;
default_random_engine g1;
default_random_engine g2;
lognormal_distribution<double> lognDis(, );
uniform_int_distribution<int> uiDis(, 1E5); int main() {
freopen("in.txt", "w+", stdout);
int T = ;
printf("%d\n", T);
while(T--) {
int N = lognDis(g1);
if(N>1E5) N%=int(1E5);
printf("%d\n", N);
for(int i=; i<N; i++) {
int Hi = uiDis(g2);
printf("%d ", Hi);
}
puts("");
}
return ;
}

Click To

 

SCNU 2015ACM新生赛初赛【1006. 3D打印】解题报告的更多相关文章

  1. SCNU 2015ACM新生赛初赛【1007. ZLM的扑克牌】解题报告

            题目链接详见SCNU 2015新生网络赛 1007. ZLM的扑克牌 .         其实我在想这题的时候,还想过要不要设置求最小的排列,并且对于回文数字的话,可以把扑克牌折起来( ...

  2. SCNU 2015ACM新生赛初赛【1001~1011】个人解题思路

            题目1001:       大意:已知$n$个角色,$m$种怪物种族,$k$个怪物,给出一组角色编号,编号$P_{i}$的角色能肝死编号$i$的怪物,对于给定的一组怪物编号,为了打通关 ...

  3. SCNU 2015ACM新生赛决赛【F. Oyk闯机关】解题报告

            题目大意:一个$N$$\times$$N$的阵列,每个格子有$X_{ij}$个调和之音,若每次只能选择走右边或下边,从左上角出发走到右下角,问最多能收集到多少个调和之音?       ...

  4. SCNU ACM 2016新生赛初赛 解题报告

    新生初赛题目.解题思路.参考代码一览 1001. 无聊的日常 Problem Description 两位小朋友小A和小B无聊时玩了个游戏,在限定时间内说出一排数字,那边说出的数大就赢,你的工作是帮他 ...

  5. 2013级新生程序设计基础竞赛-正式赛 F 异或最大值 解题报告

    F - 异或最大值 Time Limit: 2000/1000MS (Java/Others)      Memory Limit: 128000/64000KB (Java/Others) Subm ...

  6. LeetCode 892 Surface Area of 3D Shapes 解题报告

    题目要求 On a N * N grid, we place some 1 * 1 * 1 cubes. Each value v = grid[i][j] represents a tower of ...

  7. 【LeetCode】892. Surface Area of 3D Shapes 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 日期 题目地址:https://leetcode.c ...

  8. LeetCode 883 Projection Area of 3D Shapes 解题报告

    题目要求 On a N * N grid, we place some 1 * 1 * 1 cubes that are axis-aligned with the x, y, and z axes. ...

  9. 安徽师大附中%你赛day5 T3 树上行走 解题报告

    树上行走 题目背景 \(\mathrm{Smart}\) 的脑洞非常大, 经常幻想出一些奇怪的东西. 题目描述 某一天,\(\mathrm{Smart}\) 幻想出了一棵没有边际的二叉树,脑补着在那棵 ...

随机推荐

  1. 前端学HTTP之摘要认证

    前面的话 上一篇介绍的基本认证便捷灵活,但极不安全.用户名和密码都是以明文形式传送的,也没有采取任何措施防止对报文的篡改.安全使用基本认证的唯一方式就是将其与SSL配合使用 摘要认证与基本认证兼容,但 ...

  2. Android线程管理之ExecutorService线程池

    前言: 上篇学习了线程Thread的使用,今天来学习一下线程池ExecutorService. 线程管理相关文章地址: Android线程管理之Thread使用总结 Android线程管理之Execu ...

  3. 一个技术汪的开源梦 —— 基于 .Net Core 的公共组件之 Http 请求客户端

    一个技术汪的开源梦 —— 目录 想必大家在项目开发的时候应该都在程序中调用过自己内部的接口或者使用过第三方提供的接口,咱今天不讨论 REST ,最常用的请求应该就是 GET 和 POST 了,那下面开 ...

  4. JQuery中的工具函数总结

    前提引入 前提当然也是要引入Jquery啦... <script src="http://libs.baidu.com/jquery/1.9.0/jquery.js" typ ...

  5. 【目录】JUC集合框架目录

    JUC集合框架的目录整理如下: 1. [JUC]JUC集合框架综述 2. [JUC]JDK1.8源码分析之ConcurrentHashMap(一) 3. [JUC]JDK1.8源码分析之Concurr ...

  6. JavaScript结构三层——思想快速介绍

    本文版权归博客园和作者吴双本人所有,转载和爬虫请注明原文地址 http://www.cnblogs.com/tdws/,我是博客园蜗牛,我们共同进步. 今天讨论的是什么 如果你的工作中需要写JavaS ...

  7. C++双缓冲多线程分析大文件词频

    实习生活告一段落,我正式从一名.NET程序员转入Java阵营,不得不说刚开始用Java的东西是多么的不习惯,但是经过三个月的使用与开发,我也发现了Java的优势:不在于语言,而在于开源.这意味着有更多 ...

  8. linux vi 命令大全

    进入vi的命令 vi filename :打开或新建文件,并将光标置于第一行首 vi +n filename :打开文件,并将光标置于第n行首 vi + filename :打开文件,并将光标置于最后 ...

  9. spring aop对service层日志和异常的处理

    1.aop是什么 AOP是Aspect Oriented Programming的缩写,意思是面向切面编程,与OOP(Object Oriented Programming)面向对象编程对等,都是一种 ...

  10. JAVA 问题集中之处以及解决的办法

    也许当你看的时候,你可能认为这些都是简单的问题,有什么好记的.其实不是,我认为,我们往往是因为粗心而造成的错误,当你在开发中碰到这些问题时,你能一下看出来是什么错误,达到提高效率.而且往往你把小的问题 ...