工科楼北面的那个坑

#include <stdio.h>
#include <stdlib.h>

typedef struct mdata
{
    int *pTime;
    int width;
    int hight;
    struct mdata *pre;
    struct mdata *next;
}mhole;

mhole *setHole(mhole *,int ,int ,int *);    //插入结点
void pourTime(mhole *cur);                  //计算灌水时间
void printTime(int *pTime,int N);           //输出灌水时间

int main()
{
    mhole *left,*right,*pt,*curHole;
    int N,mCount;
    int mWidth,mHight;
    int *time;

    left = (mhole*)malloc (sizeof(mhole));   //初始化左边界
    left->width = 0;
    left->hight = 1000000;
    left->pTime = NULL;
    left->pre = left->next = NULL;


    scanf("%d",&N);
    time = (int*)calloc(N,sizeof(mhole));    //time分配空间

    pt = curHole = left;                     //当前结点,坑底位置最低结点
    for(mCount = 0;mCount<N;mCount++){
        scanf("%d%d",&mWidth,&mHight);
        curHole = setHole(curHole,mWidth,mHight,time+mCount);
        if(pt->hight > mHight)                //坑底位置最低结点
            pt = curHole;
    }
    right = setHole(curHole,0,1000000,NULL);

    pourTime(pt);
    printTime(time,N);

    return 0;
}
mhole *setHole(mhole *preHole,int width,int hight,int *ptime)
{
    mhole *curHole = (mhole *)malloc(sizeof(mhole));
    curHole->width = width;
    curHole->hight = hight;
    curHole->pTime = ptime;
    curHole->pre = preHole;
    curHole->next = NULL;

    preHole->next = curHole;
    return curHole;
}
void pourTime(mhole * curHole)
{
    mhole *cur = curHole,*pt;
    int myclock = 0;
    while(cur->pre->hight != cur->next->hight){
        *(cur->pTime) = myclock + cur->width;
        //计算当前时间,合并以灌满结点
        if(cur->pre->hight > cur->next->hight){
            myclock += (cur->next->hight - cur->hight)*cur->width;
            cur->next->width += cur->width;
            //摘下pt,释放结点
            cur->pre->next = cur->next;
            cur->next->pre = cur->pre;
            pt = cur;
            cur = cur->next;
            free(pt);
        }
        else{
            myclock += (cur->pre->hight - cur->hight)*cur->width;
            cur->pre->width += cur->width;

            cur->pre->next = cur->next;
            cur->next->pre = cur->pre;
            pt = cur;
            cur = cur->pre;
            free(pt);
        }
        //移动至下一结点,此结点为当前坑底最低位置
        if(cur->hight < cur->pre->hight&&cur->hight < cur->next->hight)
            continue;
        else if(cur->pre->hight > cur->next->hight){     //右移
            while(cur->hight > cur->next->hight)
                cur = cur->next;
            }else {
                while(cur->hight >cur->pre->hight)
                    cur = cur->pre;
            }
    }
    myclock += cur->width;
    *(cur->pTime) = myclock;
}
void printTime(int *pTime,int N)
{
    while(N--){
        printf("%d\n",*pTime++);
    }
}


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
描述   在 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 行上分别有两个整数,分别表示平面的宽度和高度。 输出   输出每个平面被水覆盖的时间。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值