AOJ-AHU-OJ-558 窃取任务

来源:互联网 发布:linux snmp 无法启动 编辑:程序博客网 时间:2024/05/16 00:39
窃取任务
Time Limit: 1000 ms   Memory Limit: 64 MB
Description
战争期间,双方互打信息战,我军准备去敌方一条战斗主线上的信息塔窃取他们的信息。敌方的信息塔排成了一条线,每个信息塔都会同时向两侧(两端的塔只向一侧)严格比自己高的最近的信息塔传送信息。现在时间紧迫,我们只能去其中一个信息塔,为了最高效的窃取敌人的信息,我们必须选择其中信息接收量最大的塔。现在请你去执行这个窃取任务。

Input
第1行,一个整数N(1<=N<=50000),表示这条线上有多少个信息塔。
第2行,N个整数h1到hn,其中hi(1<=hi<=2000000)表示第i个塔的高度。

Output
仅1行,一个整数i表示信息接收量最大的塔的编号,如果有多个输出编号最小的。

Sample Input
OriginalTransformed
45 2 6 7

Sample Output
OriginalTransformed
3

Source
ZGF

————————————————————开森的分割线————————————————————
思路:本题AC得神清气爽!咳咳。。。。。。首先我们在POJ
Largest Rectangle in a Histogram最大矩形直方图这道题当中艰难地学会了单调栈。这一题刚好拿来练手。首先我们要把问题简单化。双向发射信息有些难以理解。我们假设所有信号塔只能够向右发射信息。这时候我们看到,一个塔,只要右边没遇见比它高的塔,就必须一直发射信息直到找到了比它高的塔。每个塔都是这样。一旦遇到了比当前塔高的某个塔T,就需要回过头计算从当前塔直到第一个比T要高的,这之间所有塔都必须向T发射信息。然后,这些塔计算完毕,对了,出栈!这就是维护一个单调递减的栈。
准确地说,维护一个不增的栈。完成之后,再从右到左考虑,同理。
代码如下:
#include <stdio.h>#include <string.h>#include <math.h>#include <stdlib.h>int a[50010], b[50010];//b[]数组保存了每个塔得到的信息量int sta[50010];int main(){    int n, top, pos, height;    scanf("%d", &n);    for(int i = 0; i < n; i++)      scanf("%d", a+i);    memset(b, 0, sizeof(b));    //首先维护一个单调递减的栈,只看向右发射信息的情况    top = -1;  sta[++top] = a[0];    for(int i = 1; i < n; i++){        pos = i;//记录此塔的位置,以备出栈        height = a[i];        while(sta[top] < height && top != -1){//认真思考,为什么不取等于号。            top--;//一旦打破单调性,出栈            b[pos]++;//出去一个,T塔信息量+1        }        sta[++top] = height;//单调地入栈    }    //接着反过来维护一个单调递减的栈,只看向左发射信息的情况,复制之后稍微修改即可。    top = -1;  sta[++top] = a[n-1];    for(int i = n-2; i >= 0; i--){        pos = i;        height = a[i];        while(sta[top] < height && top != -1){            top--;            b[pos]++;        }        sta[++top] = height;    }    int maxi = -1, ans;    for(int i = 0; i < n; i++)        if(b[i] > maxi){            maxi = b[i];            ans = i+1;        }    printf("%d\n", ans);return 0;}



0 0
原创粉丝点击