0
点赞
收藏
分享

微信扫一扫

导弹拦截的(题解)

罗蓁蓁 2022-01-26 阅读 43

各位dalao~ ~~有锅莫喷orz..... 贴AC代码

#include<iostream>
#include<cstdio>
using namespace std;
int n=0;//n是用来计数总的个数
int a[100050];
int low[100050]; 
int d=0;//d是长度 
int find(int x)
{
    int l=1,r=d,mid;
    while(l<r)
    {
        mid=(l+r)/2;
        if(x<=low[mid])
        {
            l=mid+1; 
        }
        else
        {
            r=mid;
        }       
    }
    /*现在的数列如果要插入12;
    现在的栈中的剩余元素是 28 19 15 14 13 11 9 6 4 2 1*//*low[mid]=low[5]=13*/
    /*l=6*/
    /*循环完了以后,l=6=r这时候就不会在进入while的这个函数,mid这时候仍然为上一步的mid,需要最后更新一次*/
    mid=(l+r)/2;
    low[mid]=x;
}
int find2(int x)
{
    int l=1,r=d,mid;
    while(l<r)
    {
        mid=(l+r)/2;
        if(x>low[mid])
        {
            l=mid+1; 
        }
        else
        {
            r=mid;
        }       
    }
    mid=(l+r)/2;
    low[mid]=x;
}
/*389 207 155 300 299 170 158 65*/
int main()
{
    while(cin>>a[++n]);
    n--;//栈中的序列和实际的a序列是完全不相同的两个,必须要分开记录 
    for(int i=1;i<=n;i++)
    {
        /*开始的时候不去给low定义初值,如果不写d==0的特判就会输出d=0,不会进入函数直接输出定义的值*/
        if(d==0||a[i]<=low[d])//注意要区分上升序列和不下降序列的等号差别 
        {
            d++;
            low[d]=a[i]; 
        }
        else
        {
            find(a[i]);
        }
    }
    cout<<d<<endl;//an已经成功了一半lie
/*已经输出了维护好栈以后的栈的长度*/
    d=0;
    /*这一问其实实际就是要求去一个最长上升(严格的上升,不带等号,带等号一台设备就可以搞定了)子序列的长度orz*/
    for(int i=1;i<=n;i++)
    {
        if(d==0||a[i]>low[d])
        {
            d++;
            low[d]=a[i];
        }
        else 
        {
            find2(a[i]);
        }
    } 
    cout<<d<<endl;

}

菜鸡lue·~~~

举报

相关推荐

0 条评论