2017年8月12日训练日记

来源:互联网 发布:台湾观光局数据 编辑:程序博客网 时间:2024/06/08 11:21

       集训时间已经过了一半,自打从高三以来时间观念一直比较重,有个定理说你完成一件事总比你预计中要花费更多的时间,对于我这种拖沓的人非常适用,还是那句话:改嘛。学而不思则罔,思而不学则殆,学习要讲方法,但只有方法还不够,主要还是去做啊。

       说一说单调队列吧,

       单调队列:队列中元素之间的关系具有单调性(注意一般是严格单调的),而且,队首和队尾都可以进行出队操作,只有队尾可以进行入队操作。

       单调队列的常用操作如下:
      (1)插入:若新元素从队尾插入后会破坏单调性,则删除队尾元素,直到插入后不再破坏单调性为止,再将其插入单调队列。
      (2)获取最优(最大、最小)值:访问首尾元素。

       一般的情况下单调队列有两种创建方式:
      (1). 用q数组存放数值,id数组存放对应下标

int head1=1,tail1=0;for(i=1;i<=n;i++) //创建一个递增队列{        while(head<=tail&&que[tail]>=a[i]) tail1--;        tail1++;        que[tail1]=a[i]; id[tail]=i;}
       (2).直接用q数组存放下标,

int head=1,tail=0;for(i=1;i<=n;i++)  ////创建一个递增队列{        while(head<=tail&a[que[tail1]]>=a[i]) tail1--;        que[++tail1]=i;}

     对于二分的题目说几点要注意的:

     (1).按精度输出尽量用cout<<fixed<<setprecision(i)<<cnt<<endl;

     (2).当对double取绝对值用fabs而不是abs,

     (3).上下限调整,我有理解的一点是这样,比如说以下代码,说Farmer john有m头奶牛要安置,牛尽量远,求最近的两个牛间距离最大是多少

while(left<right)        {            mid=(left+right)/2;  //用mid模拟最近距离,求出可以放num头牛          num=1; temp=a[0];            for(i=1;i<n;i++)            {                if(a[i]-temp>mid) {num++; temp=a[i];}           }            if(num>=m) left=mid+1;  //如果num=m说明可以放的下m头牛,但为了取更大这时候要让left=mid+1,也就让mid去尝试更大的值          else right=mid;        }    printf("%d",left);

还有一种输出方法:

while(left<right)    {        mid=(left+right)/2;        num=1; temp=a[0];        for(i=1;i<n;i++)        {            if(a[i]-temp>mid) {num++; temp=a[i];}  //注意是大于号不是大于等于号        }        if(num>=m) left=mid+1;        else {right=mid;ans=mid;}    }    printf("%d",ans);