UVa 1442 (线性扫描) Cave

对于一个水坑,水平面肯定是相等的。(废话,不然为什么叫水ping面)

因为水面不能碰到天花板,所以将水面向两边延伸要么碰到墙壁要么延伸到洞穴外面去。

设h(i)表示向左延伸不会碰到天花板的最高水平面,可以线性从左往右扫描计算出来。

用level标记当前水平面高度,level初始为s[0]

  • 如果p[i] > level,说明水遇到墙壁了,需要把水面提到p[i]上来
  • 如果s[i] < level,说明水遇到天花板了,需要把水面降到s[i]去
  • 否则,他们都在同一个水坑里面,水位高度不变

同理,从右往左扫能计算出一个向右延伸不会碰到天花板的水面最大高度。二者取最小值就是最终水面的高度。

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4
 5 const int maxn = 1000000 + 10;
 6 int p[maxn], s[maxn], h[maxn];
 7
 8 int main()
 9 {
10     //freopen("in.txt", "r", stdin);
11
12     int T; scanf("%d", &T);
13     while(T--)
14     {
15         int n; scanf("%d", &n);
16         for(int i = 0; i < n; i++) scanf("%d", &p[i]);
17         for(int i = 0; i < n; i++) scanf("%d", &s[i]);
18         int level = s[0];
19         int ans = 0;
20         for(int i = 0; i < n; i++)
21         {
22             if(level > s[i]) level = s[i];
23             if(level < p[i]) level = p[i];
24             h[i] = level;
25         }
26
27         level = s[n-1];
28         for(int i = n-1; i >= 0; i--)
29         {
30             if(level > s[i]) level = s[i];
31             if(level < p[i]) level = p[i];
32             ans += min(level, h[i]) - p[i];
33         }
34
35         printf("%d\n", ans);
36     }
37
38     return 0;
39 }

代码君

时间: 2024-08-25 19:02:57

UVa 1442 (线性扫描) Cave的相关文章

[hihocoder 1249 Xiongnu&#39;s Land]线性扫描

2015区域赛北京赛区的三水,当时在赛场上没做出的原因是复杂度分析不正确导致把方法想复杂了.近来复习复杂度分析,觉得不能只是笼统地看渐进复杂度(big-O),更应根据算法的伪码计算真正的以基本操作数为变量的时间复杂度T(n). 题意:在二维坐标系第一象限中,将一块顶点在原点边长为R的正方形土地用直线x=n一分为二,左侧分给Wei,右侧分给Huo. 土地中包含N个绿洲,每个绿洲是一个矩形,其位置和大小用四元组(L,T,W,H)表示,其中(L,T)为其左上方顶点的坐标,W,H为其宽度和高度.绿洲互不

Uva 1442

题目:Uva 1442 思路:处理出每一点能往左和往右延伸的不碰到天花板的最长高度.然后答案就是min(l[i],r[i])-p[i]. #include<bits/stdc++.h> using namespace std; int hu[1000100]; int hd[1000100]; int l[1000100]; int r[1000100]; int main(){ //freopen("in.txt","r",stdin); int T;

[ An Ac a Day ^_^ ] HihoCoder 1249 Xiongnu&#39;s Land 线性扫描

拿到了icpc北京站的参赛名额 感谢亮哥~ 虽然是地狱之战 但也要全力以赴! 题意: 有一片沙漠 n片绿洲 让你用一条线分成两部分 左≥右 而且分割线要尽量靠右 问线的位置 思路: 网上说可以二分 没太看懂…… 还有一种思路就是线性扫描 将二维的图化成一维的线 然后从头扫一遍 遇到左≥sum/2时试探着向右继续扫 最后输出答案 1 #include<stdio.h> 2 #include<iostream> 3 #include<algorithm> 4 #includ

【CF676C】Vasya and String(二分查找,线性扫描尺取法)

题意: 给出一个长度为n的字符串,只有字符'a'和'b'.最多能改变k个字符,即把'a'变成'b'或把'b'变成'a'. 问改变后的最长连续相同字符的字串长度为多少. 首先是二分查找,好想也好写 1 var s:array[0..100000]of longint; 2 ch:ansistring; 3 n,k,i,l,r,mid,last,ans:longint; 4 5 function max(x,y:longint):longint; 6 begin 7 if x>y then exit

线性扫描寄存器分配算法--相关论文

http://cs.au.dk/~mis/dOvs/slides/Kevin-linear-scan-reg-alloc.pdf ftp://ftp.ssw.uni-linz.ac.at/pub/Papers/Moe02.PDF Greedy Register Allocation in LLVM 3.0 http://blog.llvm.org/2011/09/greedy-register-allocation-in-llvm-30.html http://lists.cs.uiuc.edu

75.Sort Colors(法1快排法2线性扫描统计赋值)

Given an array with n objects colored red, white or blue,sort them so that objects of the same color are adjacent, with the colors inthe order red, white and blue. Here, we will use the integers 0, 1, and 2 to represent the color red,white, and blue

UVA 1442 Cave 洞穴 (贪心+扫描)

题意:有一个洞穴,每个位置有一个底的高度p[i],和对应顶的高度s[i],要往里面尽量放燃料,要求燃料不能碰到顶,可以无限接近. 题解:制约燃料储放的就是顶的高度了,分别求出设当前储放位置的向两边的延伸不会碰到顶的最大高度. 设当前最大高度为level,起始位置为顶高,移动到下一格的时如果碰到顶,那么降低到s[i],如果小于p[i],那么就就提高到p[i]. 两边都扫一遍,然后取最小高度. 试了试输入优化,对于这种大量数据输入效果不错,节省了大约100ms. #include<bits/stdc

uva 1442:Cave(贪心)

题意:一个洞穴长n,告诉你每个位置的地面高度和顶部高度,让你往里灌水,要求水不能碰到天花板(但可以无限接近).求最多的水量.(洞穴两边视为封闭) 思路:如果知道一个位置向左看最高可以多高,向右看最高可以多高,就可以知道这个位置最终的高度了.方法是扫两次.每次扫的时候,定义一个之前最高值.若之前最高值高于现在的顶,则下降至顶.若低于底,则上升至底(因为后面的这种高度能被这个底挡住).如果在中间则不用变. 代码: #include <cstdio> #include <cstring>

【CF652C】Foe Pairs(线性扫描)

题意:给你1-n的一个排列和m组数对,问有多少区间不包含任意一个数对. (1?≤?n,?m?≤?3·105) 思路:数据范围过大,不能用容斥原理 f[i]表示以位置i上的数为左端点,右端点最小到哪里 不包含=总数-包含即可 1 var f,c:array[1..310000]of int64; 2 n,m,x,y,t:int64; 3 i:longint; 4 ans:int64; 5 6 function min(x,y:int64):int64; 7 begin 8 if x<y then