a tutorial on computer science

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  21 随笔 :: 0 文章 :: 17 评论 :: 0 Trackbacks
    其实这个题不该想这么久的。。。
  题目的意思是说给一个正数序列,求其中的最长的最大值-最小值大于等于M  并且  小于等于K 的长度。
     咋一看起来很麻烦,想了想也很麻烦。怎么才能保证是最长的并且大于等于M还小于等于K呢?维护一个大于等于M且小于等于K的队列?当加入新的元素之后,若不满足题目给的条件,应该从两个队列的队尾出队,但是应该出哪一个?应该出绝对位置靠前面的那个。
     上面说了一大堆,忽略了一个问题:当两个队伍的元素之差小于M的时候,无论怎么出队,都不可能再大于M了!所以当最大值减最小值小于M的时候,就不需要再出队了。所以程序的自然语言描述就是,维护一个最长的,且<=K的队列。
     上面的思路很麻烦,而且无法证明其正确性。后来发现这个题就是前几天比赛A题加了一个条件>=M。好吧,这两个条件是&&的关系,直接维护一个小于等于K的队列即可,不用管那个M了,只要在求结果的时候判断下就OK。代码如下:
#include <stdio.h>

typedef 
struct
{
  
int pos,value;
}
node;

node queueMax[
1000010],queueMin[1000010];
int mhead,mtail,nhead,ntail;

int data[1000010];

int N,M,K;

int max(int a,int b)
{
    
if(a > b)
      
return a;
    
return b;
}

int main()
{
   
int res,i;
   
while(scanf("%d%d%d",&N,&M,&K)!=EOF)
   
{
     
for(i=0;i<N;i++)
       scanf(
"%d",&data[i]);
     res 
= 0;
     mhead 
= mtail = nhead = ntail = 0;
     node tmp 
= {0,data[0]};
     queueMax[mhead
++= queueMin[nhead++= tmp;
     
int start,end; start = 0; end = -1;
     
while(end < N - 1)
     
{
       
//入队列,end++
       end++;
       
while(mtail != mhead && queueMax[mhead - 1].value < data[end])
         mhead
--;
       
while(ntail != nhead && queueMin[nhead - 1].value > data[end])       
         nhead
--;
         
       tmp.pos 
= end;
       tmp.value 
= data[end];
       queueMax[mhead
++= queueMin[nhead++= tmp;
       
       
       
//保持性质,更新队列和start 
       
       
while(ntail!= nhead && mhead != mtail && (queueMax[mtail].value - queueMin[ntail].value >K))
       
{
       
if(queueMax[mtail].pos <= queueMin[ntail].pos)
         
{
            start 
= queueMax[mtail].pos + 1;
            mtail
++;
         }

         
else
         
{
            start 
= queueMin[ntail].pos + 1;
            ntail
++;
         }

       }

       
       
//找res
       if((queueMax[mtail].value - queueMin[ntail].value >= M && queueMax[mtail].value - queueMin[ntail].value<=K) && res < end - start + 1)
         res 
= end - start + 1;
         
     }

     printf(
"%d\n",res);
   }

   
return 0;
}

posted on 2012-03-09 14:38 bigrabbit 阅读(879) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理