成绩 | 10 | 开启时间 | 2022年09月26日 星期一 00:01 |
折扣 | 0.9 | 折扣时间 | 2022年10月16日 星期日 23:59 |
允许迟交 | 否 | 关闭时间 | 2022年10月26日 星期三 23:59 |
描述
在 LIT 综教楼后有一个深坑,关于这个坑的来历,有很多种不同的说法。其中一种说法是,在很多年以前,这个坑就已经在那里了。这种说法也被大多数人认可,这是因为该坑有一种特别的结构,想要人工建造是有相当困难的。
从横截面图来看,坑底成阶梯状,由从左至右的 1..N 个的平面构成(其中 1 ≤ N ≤ 100,000),如图:
* * : * * : * * 8 * ** * 7 * ** * 6 * ** * 5 * ********* 4 <- 高度 * ********* 3 ************** 2 ************** 1 平面 | 1 |2| 3 |
每个平面 i 可以用两个数字来描述,即它的宽度 Wi 和高度 Hi,其中 1 ≤ Wi ≤ 1,000、1 ≤ Hi ≤ 1,000,000,而这个坑最特别的地方在于坑底每个平面的高度都是不同的。每到夏天,雨水会把坑填满,而在其它的季节,则需要通过人工灌水的方式把坑填满。灌水点设在坑底位置最低的那个平面,每分钟灌水量为一个单位(即高度和宽度均为 1)。随着水位的增长,水自然会向其它平面扩散,当水将某平面覆盖且水高达到一个单位时,就认为该平面被水覆盖了。
请你计算每个平面被水覆盖的时间。
灌水 水满后自动扩散 | | * | * * | * * * * V * * V * * * * * * .... * *~~~~~~~~~~~~* * ** * *~~~~** : * *~~~~**~~~~~~* * ** * *~~~~** : * *~~~~**~~~~~~* * ** * *~~~~**~~~~~~* *~~~~**~~~~~~* * ********* *~~~~********* *~~~~********* *~~~~********* *~~~~********* *~~~~********* ************** ************** ************** ************** ************** ************** 4 分钟后 26 分钟后 50 分钟后 平面 1 被水覆盖 平面 3 被水覆盖 平面 2 被水覆盖输入
输入的第一行是一个整数 N,表示平面的数量。从第二行开始的 N 行上分别有两个整数,分别表示平面的宽度和高度。
输出
输出每个平面被水覆盖的时间。
我的思路是
设一个结构数组
下标,长,宽,flag,水(表示它是否已结束)
首先从一开始,找到一个两边flag都是0且都比它高的,找到两旁较矮的,用这个数算面积,然后这块flag=1,给水赋值。然后以较矮的为基准,再做上一次的操作,找到最低的。
但实际上这个操作用链表做更容易
单位节点初始化,下标,宽度,高度,前指针,后指针
初始化要有头指针,最低指针,最左的指针,最右指针,录入用的指针
作为一个最低的,做水的加法后,首先判断前后谁更低,确定下一次要多少水,然后移动指针做判断,此时是不是最低,最低就进下一轮,不是最低就一直移动。
最后出循环记得把最后一次水加上
#include<stdio.h>
#include "stdlib.h"
#define Max 100005
typedef struct ndi{
long long gao,kuan,diji;
struct ndi *pre;
struct ndi *next;
}kuai;
kuai data[Max];
long long ans[Max];
long long N;
int main(void){
scanf("%lld",&N);
kuai *left, *right, *prehole, *cur, *deep;
left = (kuai *)malloc(sizeof(kuai));
left->diji=-1;
left->kuan=0;
left->gao=Max;
left->next=NULL;
left->pre =NULL;
prehole=left;deep=left;
right = (kuai *)malloc(sizeof(kuai));
right->diji=-1;
right->kuan=0;
right->gao=Max;
right->next=NULL;
right->pre =NULL;//初始化完毕,开始录入
for(long long i=0;i<N;i++){
cur=(kuai *)malloc(sizeof(kuai));
scanf("%lld %lld",&cur->kuan,&cur->gao);
cur->diji=i;
cur->pre=prehole;
prehole->next=cur;
prehole=cur;
if(deep->gao>cur->gao){
deep=cur;
}
}
prehole->next=right;//搭建完毕
long long time=0;
while(deep->pre->diji!=-1||deep->next->diji!=-1) {
ans[deep->diji]=time+deep->kuan;
if(deep->pre->gao>deep->next->gao){//假如后面是低的
time+=(deep->next->gao-deep->gao )*deep->kuan;
deep->next->kuan+=deep->kuan;
deep->pre->next=deep->next;
deep->next->pre=deep->pre;
deep=deep->next;
}
else{
time+=(deep->pre->gao-deep->gao )*deep->kuan;
deep->pre->kuan+=deep->kuan;
deep->pre->next=deep->next;
deep->next->pre=deep->pre;
deep=deep->pre;
}
if(deep->gao<deep->pre->gao&&deep->gao<deep->next->gao){
continue;
}
else if(deep->gao>deep->pre->gao){//前面更低
while(deep->gao>deep->pre->gao) {
deep=deep->pre;
}
}
else{
while(deep->gao>deep->next->gao) {
deep=deep->next;
}
}
}
ans[deep->diji]=time+deep->kuan;
for(long long i=0;i<N;i++ ){
printf("%lld\n",ans[i]);
}
}