对于一个水坑,水平面肯定是相等的。(废话,不然为什么叫水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 ", ans); 36 } 37 38 return 0; 39 }