【浇水问题】解题报告

来源:互联网 发布:关联规则算法实例 编辑:程序博客网 时间:2024/05/01 12:03

浇水 (water.c/cpp/pas)【题目描述】LazyChild在青岛二中科技楼里种了一排n棵树,每棵树都有一个高度。他会枚举所有的区间,然后从区间中找出一个高度最矮的树进行浇水(照顾弱者)。由于LazyChild浇完水之后就精疲力竭了,所以请你帮助他计算每棵树都被浇了几次水。【输入文件】第一行一个整数n。第二行n个整数,分别表示每棵树的高度。【输出文件】一行n个整数用空格隔开,分别表示每棵树被浇了几次水。【样例输入】31 3 5【样例输出】3 2 1【样例解释】LazyChild枚举到了6个区间分别是[1], [3], [5], [1 3], [3 5], [1 3 5],对应的最矮的树的高度是1, 3, 5, 1, 3, 1。【数据规模和约定】对于40%的数据,n <= 1000对于100%的数据,n <= 1000000,保证每棵树的高度都不相同

这个题是一道栈的应用题目,我的超时,用王哥的程序。

L[i]维护从i向左的连续区间中,比多少个数小,如:1 4 7 5 8 6,6对应的L值为3

维护一个单调递增的堆,堆中节点序号(对应L数组和输入数据)。

#include <iostream>#include <iomanip>#include <cstring>#include <cmath>using namespace std;const char fi[] = "water.in";const char fo[] = "water.out";const int maxN = 1000010;struct Stack{  int top;  int data[maxN];};int data[maxN];long long l[maxN], r[maxN];//注意要用long long,否則超界。Stack S;int n;  void init_file()  {    freopen(fi, "r", stdin);    freopen(fo, "w", stdout);    ios::sync_with_stdio(false);  }  void init_array()  {    memset(data, 0, sizeof(data));    memset(l, 0, sizeof(l));    memset(r, 0, sizeof(r));  }    void readdata()  {    cin >> n;    for (int i = 1; i <= n; i++)      cin >> data[i];  }    void work()  {    S.top = 1;    S.data[0] = 1;//棧清空,棧頂置1。    l[1] = 1;    r[n] = 1;    for (int i = 2; i <= n; i++)    {      while (data[S.data[S.top - 1]] > data[i])      {        l[i] += l[S.data[--S.top]];      } //累加棧頂元素的l值。      l[i]++;      S.data[S.top++] = i; //入棧。    }    S.top = 1;    S.data[0] = n;//棧清空,棧頂置n。    for (int i = n - 1; i >= 1; i--)    {      while (data[S.data[S.top - 1]] > data[i])      {        r[i] += r[S.data[--S.top]];      } //累加棧頂元素的r值。      r[i]++;      S.data[S.top++] = i; //入棧。    }    for (int i = 1; i <= n; i++)    {      cout << l[i] * r[i] << " ";    }    cout << endl;  }  int main(){  init_file();  init_array();  readdata();  work();  exit(0);}//此題考察棧。//用l[i], r[i]分別表示i的左邊,右邊比i小數的個數(包括i)。//先從左到右掃描,若棧頂元素大於當前元素則出棧,//並將其l值累加到l[i],直到棧頂元素小於当前元素為止,//l[i]最後加一,並將i入棧。//再從右到左掃描,若棧頂元素大於當前元素則出棧,//並將其r值累加到r[i],直到棧頂元素小於当前元素為止,//r[i]最後加一,並將i入棧。//最後,根據乘法原理,每个元素出現在各區間的次數即為l[i] * r[i]。

原创粉丝点击