综教楼后面的深坑

难以理解为什么会超时

正确的算法可能是要更加简洁的算法?不太懂。

#include<cstdio>  
#include<string.h>  
#include<queue>  
#include<iterator>  
#include<algorithm>  
#include<vector>  
#include<list>  
#include<stack>  
using namespace std; 
 
struct HOLE 
{ 
 long long int no; 
  long long int w; 
   long long int h; 
   long long int time; //when water come to this hi  
}; 
 
list<HOLE>::iterator pos_mov(list<HOLE>::iterator); 
//pos_pr point move function  
 
void pos_cmb(list<HOLE>::iterator, list<HOLE>::iterator); 
//combine the first sructure to the second  
list<HOLE>hole; 
stack<HOLE>map; 
vector<HOLE>output; 
 
int main() 
{ 
 HOLE temp; 
 long long int N, n; 
    scanf("%lld", &N); 
 getchar(); 
 temp.time = 0; 
 long long int highest = 0; 
 for (n = 0; n < N; n++) 
 { 
      temp.no = n; 
       scanf("%lld %lld", &temp.w, &temp.h); 
      getchar(); 
     hole.push_back(temp); 
      output.push_back(temp); 
        highest = (highest > temp.h) ? highest : temp.h; 
 
   } 
  //looking for the lowest  
  list<HOLE>::iterator pos1, pos2; 
 pos1 = hole.begin(); 
   pos2 = hole.begin(); 
   long long int time_sum = 0, width_sum = 0; 
 while (1) 
  { 
      if (pos1 == hole.end()) 
        { 
          break; 
     } 
      if ((*pos1).h < (*pos2).h) 
      { 
          pos2 = pos1; 
       } 
      width_sum += (*pos1).w; 
        time_sum += (highest + 1 - (*pos1).h) * (*pos1).w; 
     pos1++; 
    } 
  //  
    list<HOLE>::iterator pos_pr, pos_lf, pos_rt; 
 long long int pos_past; 
    pos_pr = pos2; 
 pos_past = (*pos_pr).no; 
   pos_lf = pos_pr; 
   pos_rt = pos_pr;    //left right present point on the same place, which means the begin  
 
 
 
    while (1) 
  { 
      if (hole.size() == 1)  //when hole become one, end  
        { 
 
         //count  
           break; 
     } 
      pos_pr = pos_mov(pos_pr);  //move pos_pr to correct place  
     pos_lf = pos_pr; 
       pos_rt = pos_pr; 
       if (pos_pr != hole.begin()) 
        { 
          pos_lf--; 
          pos_rt++; 
      } 
      else if (pos_pr == hole.begin()) 
       { 
          pos_lf = hole.end(); 
           pos_rt++; 
      } 
 
     if (pos_lf != hole.end() && pos_rt != hole.end()) //pos_pr not in begin or end  
        { 
          if ((*pos_lf).h > (*pos_rt).h) 
          { 
              pos_cmb(pos_pr, pos_rt); 
               pos_pr = pos_rt; 
           } 
          else if ((*pos_lf).h < (*pos_rt).h) 
         { 
              pos_cmb(pos_pr, pos_lf); 
               pos_pr = pos_lf; 
           } 
      } 
      else if (pos_lf == hole.end() && pos_rt != hole.end()) //pos_pr in begin  
      { 
          pos_cmb(pos_pr, pos_rt); 
           pos_pr = pos_rt; 
       } 
      else if (pos_lf != hole.end() && pos_rt == hole.end()) //pos_pr in end  
        { 
          pos_cmb(pos_pr, pos_lf); 
           pos_pr = pos_lf; 
       } 
  } 
  temp.h = (hole.front()).h; 
 temp.w = (hole.front()).w; 
 temp.time = (hole.front()).w; 
  temp.no = (hole.front()).no; 
   map.push(temp); 
 
   while (1) 
  { 
      if (map.size() == 0) 
       { 
          break; 
     } 
      (output[(map.top()).no]).time = time_sum - (map.top()).time + (map.top()).w; 
       time_sum -= (map.top()).time; 
      map.pop(); 
 } 
 
 for (n = 0; n < N; n++) 
 { 
      printf("%lld\n", (output[n]).time); 
    } 
 
} 
 
list<HOLE>::iterator pos_mov(list<HOLE>::iterator present) 
{ 
 list<HOLE>::iterator left, right, last; 
  int flag = 0; 
  left = present; 
    right = present; 
   last = present; 
    while (1) 
  { 
      left = present; 
        right = present; 
       if (present != hole.begin()) 
       { 
          left--; 
            right++; 
       } 
      else if (present == hole.begin()) 
      { 
          left = hole.end(); 
         right++; 
       } 
      if (flag == 1) 
     { 
          break; 
     } 
      if (left == hole.end()) //on begin  
        { 
          if (right == hole.end()) 
           { 
              flag = 1; 
              continue; 
          } 
          else if ((*right).h > (*present).h) 
         { 
              flag = 1; 
              continue; 
          } 
          else 
           { 
              last = present; 
                present = right; 
               continue; 
          } 
      } 
      else if (right == hole.end())   //on end  
      { 
 
         if ((*left).h > (*present).h) 
           { 
              flag = 1; 
              continue; 
          } 
          else 
           { 
              last = present; 
                present = left; 
                continue; 
          } 
      } 
      //on middle  
       else 
       { 
          if ((*left).h > (*present).h && (*right).h> (*present).h) 
            { 
              flag = 1; 
              continue; 
          } 
          else if ((*left).h < (*present).h && (*right).h < (*present).h) 
          { 
              if ((*left).h < (*right).h) 
             { 
                  present = left; 
                    continue; 
              } 
              else 
               { 
                  present = right; 
                   continue; 
              } 
          } 
          else if ((*left).h > (*present).h) 
          { 
              present = right; 
           } 
          else if ((*right).h > (*present).h) 
         { 
              present = left; 
            } 
      } 
  } 
 
 return present; 
} 
 
void pos_cmb(list<HOLE>::iterator Orig, list<HOLE>::iterator Desti) 
{ 
   HOLE map_temp; 
 map_temp.no = (*Orig).no; 
  map_temp.w = (*Orig).w; 
    map_temp.h = (*Orig).h; 
    map_temp.time = ((*Desti).h - (*Orig).h) * (*Orig).w; 
  map.push(map_temp); 
    (*Desti).w += (*Orig).w; 
   hole.erase(Orig); 
}  


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值