1 solutions
-
0
C++ :
/*对于每个建筑物,只需要找到其能够扩展到的最大宽度即可。也就是这个建筑物的左右两边 的比它低或等于它的建筑物个数。如何用单调队列呢?我们从1~n依次进队,维护一个单调 递减序列。每次加入元素后维护其单调性,当然这样做必然会使一些元素出队,出队的元素 一定要比当前加入的元素小,也就是说当前元素就是出队的元素能在右侧达到的最远的建筑物! 注意,要让h[n+1]=0并且让该元素入队一次(会使当前队列中的所有元素出队),保证每个 元素都有其“右极限”的值。要求“左极限”同理,只需从n~0循环即可,注意0这道题是对 单调队列的变形使用。由于问题的结果具有单调性,很好的利用出队元素的特性.*/ #include<iostream> #include<cstring> #include<cstdio> using namespace std; long long q[400001],l[400001],r[400001],a[400001]; long long n,head,tail; int main() { //freopen("gg6.in","r",stdin); //freopen("gg6.out","w",stdout); cin>>n; for(int i=1;i<=n;i++)cin>>a[i]; head=1;tail=0; for(int i=1;i<=n+1;i++) { while(head<=tail && a[q[tail]]>a[i]) { r[q[tail]]=i; tail--; } tail++; q[tail]=i; } head=1;tail=0; for(int i=n;i>=0;i--) { while(head<=tail && a[q[tail]]>a[i]) { l[q[tail]]=i; tail--; } tail++; q[tail]=i; } long long tot=0; for(int i=1;i<=n;i++) if(tot<(r[i]-l[i]-1)*a[i]) { //cout<<r[i]-l[i]<<' '<<a[i]<<endl; tot=(r[i]-l[i]-1)*a[i]; } cout<<tot<<endl; }
Pascal :
var l,r,q,a:array[0..400005] of longint; ans:qword; n,m,head,tail,i:longint; function max(xx,yy:qword):qword; begin if xx<=yy then exit(yy); exit(xx); end; begin readln(n); for i:=1 to n do read(a[i]); l[1]:=1;q[1]:=1;head:=1;tail:=1; for i:=2 to n do begin while (tail>=head) and (a[q[tail]]>=a[i]) do dec(tail); l[i]:=q[tail]+1; inc(tail); q[tail]:=i; end; q[1]:=n+1;head:=1;tail:=1;a[n+1]:=0; for i:=n downto 1 do begin while (tail>=head) and(a[q[tail]]>=a[i]) do dec(tail); r[i]:=q[tail]-1; inc(tail);q[tail]:=i; end; ans:=0; for i:=1 to n do ans:=max(ans,qword(a[i])*(r[i]-l[i]+1)); writeln(ans); end.
Java :
import java.util.Scanner; public class Main { public int largestArea(int[] height){ if(height == null || height.length == 0) return 0; return largestArea(height, height.length); } private int largestArea(int[] height, int n) { int[]left = new int[n]; int[]right = new int[n]; left[0] = 0; right[n-1] = n-1; for (int i = 1; i < n; i++) { // 找到最左边的比它大的元素 int last = i; while (last >= 1 && height[i] <= height[last-1]) last = left[last-1]; left[i] = last; } for (int i = n-2; i >= 0; i--) { // 找到最右边的比它大的元素 int last = i; while (last < n - 1 && height[i] <= height[last+1]) last = right[last+1]; right[i] = last; } int ans = 0; for (int i = 0; i < n; i++) ans = Math.max(ans,(right[i]-left[i]+1)*height[i]); return ans; } public static void main(String[] args) { Main test = new Main(); Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] arr = new int[n]; for (int i = 0; i < n; i++) arr[i] = sc.nextInt(); System.out.println(test.largestArea(arr)); } }
- 1
Information
- ID
- 547
- Time
- 1000ms
- Memory
- 128MiB
- Difficulty
- (None)
- Tags
- # Submissions
- 0
- Accepted
- 0
- Uploaded By