• 1743 反转卡片


    漂亮妹子点击就送:http://codevs.cn/problem/1743/
     
    题目描述 Description

    【dzy493941464|yywyzdzr原创】 

    小A将N张卡片整齐地排成一排,其中每张卡片上写了1~N的一个整数,每张卡片上的数各不相同。

    比如下图是N=5的一种情况:3 4 2 1 5

    接下来你需要按小A的要求反转卡片,使得左数第一张卡片上的数字是1。操作方法:令左数第一张卡片上的数是K,如果K=1则停止操作,否则将左数第1~K张卡片反转。

    第一次(K=3)反转后得到:2 4 3 1 5

    第二次(K=2)反转后得到:4 2 3 1 5

    第三次(K=4)反转后得到:1 3 2 4 5

    可见反转3次后,左数第一张卡片上的数变成了1,操作停止。

    你的任务是,对于一种排列情况,计算要反转的次数。你可以假设小A不会让你操作超过100000次。

    输入描述 Input Description

    第1行一个整数N

    第2行N个整数,为1~N的一个全排列。

    输出描述 Output Description

    仅1行,输出一个整数表示要操作的次数。

    如果经过有限次操作仍无法满足要求,输出-1。

    样例输入 Sample Input

    5

    3 4 2 1 5

    样例输出 Sample Output

    3

    数据范围及提示 Data Size & Hint

    0<N≤300,000。

    并没有输出-1就A掉了

    //这题不知道能不能直接按照它说的来做
    
    //试一下
    
    //在每个节点上记录这个点上的数字和数组下标
    //查找现在树中最左边点的,如果它的数字==1,那就是完成了 
    //否则就旋转。
    
    //其实不用记录数字,只记录下标,然后去原数组中找对应下标的数字是几就可以 
    
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int N=3e5+5;
    
    int n;
    int a[N];
    struct NODE
    {
        NODE *fa;
        NODE *son[2];
        int id,size;
        bool rev;
    }node[N];
    
    typedef NODE* Tree;
    Tree Root,now_node,null;
    
    inline int read()
    {
        char c=getchar();int num=0;
        for(;!isdigit(c);c=getchar());
        for(;isdigit(c);c=getchar())
            num=num*10+c-'0';
        return num;
    }
    
    inline void init()
    {
        node->fa=node->son[0]=node->son[1]=node;
        Root=now_node=null=node;
    }
    
    inline Tree new_node(int id,Tree fa)
    {
        ++now_node;
        now_node->id=id;
        now_node->fa=fa;
        now_node->son[0]=now_node->son[1]=null;
        return now_node;
    }
    
    inline void update(Tree root)
    {
        root->size=root->son[0]->size+root->son[1]->size+1;
    }
    
    Tree build(Tree &root,int l,int r,Tree fa)
    {
        if(l>r)
            return null;
        int mid=l+r>>1;
        root=new_node(mid-1,fa);
        if(l<r)
        {
            build(root->son[0],l,mid-1,root);
            build(root->son[1],mid+1,r,root);
        }
        update(root);
    }
    
    inline bool getgx(Tree root)
    {
        return root->fa->son[1]==root;
    }
    
    inline void connect(Tree root,Tree fa,bool flag)
    {
        if(fa!=null)
            fa->son[flag]=root;
        root->fa=fa;
    }
    
    inline void rotate(Tree root)
    {
        Tree fa=root->fa;
        bool a=getgx(root),b=!a;
        connect(root->son[b],fa,a);
        connect(root,fa->fa,getgx(fa));
        connect(fa,root,b);
        update(fa);
        update(root);
        if(root->fa==null)
            Root=root;
    }
    
    inline void down(Tree root)
    {
        if(root->rev)
        {
            swap(root->son[0],root->son[1]);
            if(root->son[0]!=null)
                root->son[0]->rev^=1;
            if(root->son[1]!=null)
                root->son[1]->rev^=1;
            root->rev=0;
        }
    }
    
    inline void splay(Tree root,Tree goal)
    {
        down(root);
        for(;root->fa!=goal;rotate(root))
        {
            if(root->fa->fa!=goal)
                rotate(getgx(root)==getgx(root->fa)?root->fa:root);
        }
    }
    
    inline Tree find(Tree root,int pos)
    {
        down(root);
        int left=root->son[0]->size;
        if(left+1==pos)
            return root;
        if(left>=pos)
            return find(root->son[0],pos);
        return find(root->son[1],pos-left-1);
    }
    
    inline void reverse(int l,int r)
    {
        Tree a=find(Root,l),b=find(Root,r+2);
        splay(a,null);
        splay(b,a);
        b->son[0]->rev^=1;
    }
    
    
    int main()
    {
        init();
        n=read();
        for(int i=1;i<=n;++i)
            a[i]=read();
        build(Root,1,n+2,null);
        Tree ans;
        for(int i=0;i<=100000;++i)
        {
            ans=find(Root,2);
            if(a[ans->id]==1)
            {
                printf("%d",i);
                exit(0);
            }
            reverse(1,a[ans->id]);
        }
        return 0;
    }
  • 相关阅读:
    scala学习笔记:理解stream和view
    scala学习笔记:变量声明中的模式
    scala学习笔记:理解并行集合par
    快速了解Scala技术栈
    scala学习笔记:控制抽象
    scala中的call-by-name和call-by-value
    scala学习笔记:各种奇怪的写法
    scala学习笔记:match与unapply()
    scala学习笔记:无参函数
    scala学习笔记:函数与方法
  • 原文地址:https://www.cnblogs.com/lovewhy/p/8778436.html
Copyright © 2020-2023  润新知