描述
在 LIT 综教楼后有一个深坑,关于这个坑的来历,有很多种不同的说法。其中一种说法是,在很多年以前,这个坑就已经在那里了。这种说法也被大多数人认可,这是因为该坑有一种特别的结构,想要人工建造是有相当困难的。
从横截面图来看,坑底成阶梯状,由从左至右的 1..N 个的平面构成(其中 1 ≤ N ≤ 100,000),如图:
每个平面 i 可以用两个数字来描述,即它的宽度 Wi 和高度 Hi,其中 1 ≤ Wi ≤ 1,000、1 ≤ Hi ≤ 1,000,000,而这个坑最特别的地方在于坑底每个平面的高度都是不同的。每到夏天,雨水会把坑填满,而在其它的季节,则需要通过人工灌水的方式把坑填满。灌水点设在坑底位置最低的那个平面,每分钟灌水量为一个单位(即高度和宽度均为 1)。随着水位的增长,水自然会向其它平面扩散,当水将某平面覆盖且水高达到一个单位时,就认为该平面被水覆盖了。
请你计算每个平面被水覆盖的时间。
输入的第一行是一个整数 N,表示平面的数量。从第二行开始的 N 行上分别有两个整数,分别表示平面的宽度和高度。
输出
输出每个平面被水覆盖的时间。
测试输入
3 4 2 2 7 6 4
测试输出
4 50 26
源代码
#include <iostream>
#include <cstdio>
#include<malloc.h>
using namespace std;
#define height 1<<30
typedef struct DuLNode{ //定义一个类似双向链表的结构
struct DuLNode *prior; //前驱指针
struct DuLNode *next; //后驱指针
int wi,hi; //宽度,高度
long long *time;
}DuLNode,*DuLinklist;
int main(int argc, const char *argv[]){
int n,wi,hi; //n表示平面的数量
long long sum=0;
DuLinklist L,p,q,low;
scanf("%d",&n);
L=(DuLinklist)malloc(sizeof(DuLNode));
L->hi=height;
L->prior=NULL;
L->next=NULL;
L->wi=0;
L->time=NULL;
long long *time=new long long[n+1];
p=L;
q=L;
low=L;
for(int i=0;i<n;i++){
scanf("%d%d",&wi,&hi);
p=(DuLinklist)malloc(sizeof(DuLNode));
p->wi=wi;
p->hi=hi;
p->time=time+i;
q->next=p;
p->prior=q;
q=p;
if(p->hi < low->hi)
low=p;
}
p=(DuLinklist)malloc(sizeof(DuLNode));
p->hi=height;
p->wi=0;
p->time=NULL;
q->next=p;
p->prior=q;
p->next=NULL;
p=low;
while(p->prior->hi != p->next->hi){
*(p->time)=sum+p->wi;
if(p->prior->hi < p->next->hi){
sum=sum+(p->prior->hi - p->hi)*(p->wi);
p->prior->wi=p->prior->wi + p->wi;
p->next->prior=p->prior;
p->prior->next=p->next;
p=p->prior;
}
else{
sum=sum+(p->next->hi - p->hi)*(p->wi);
p->next->wi=p->next->wi + p->wi;
p->next->prior=p->prior;
p->prior->next=p->next;
p=p->next;
}
if(p->prior - hi > p - hi && p->next->hi > p->hi)
continue;
if(p->prior->hi > p->hi)
while(p->hi > p->next->hi)
p=p->next;
else
while(p->hi > p->prior->hi)
p=p->prior;
}
*(p->time)=sum+p->wi;
while(n--)
printf("%d\n",*(time++));
return 0;
}