zoukankan      html  css  js  c++  java
  • hdu 4286 (list的reverse时间复杂度为n)

    list 的翻转reverse源码:

    // 将链表倒置  
    // 其算法核心是历遍链表, 每次取出一个结点, 并插入到链表起始点  
    // 历遍完成后链表满足倒置  
    template <class T, class Alloc>  
    void list<T, Alloc>::reverse()  
    {  
      if (node->next == node || link_type(node->next)->next == node) return;  
      iterator first = begin();  
      ++first;  
      while (first != end()) {  
        iterator old = first;  
        ++first;  
        transfer(begin(), old, first);  
      }  
    }  

    直接用STL中的list华丽的超时代码:

    #include<stdio.h>
    #include<iostream>
    #include<dequ>
    #include<algorithm>
    using namespace std;
    list<int>li;
    list<int>::iterator it,l,r;
    int main()
    {
        int _case,n;
        int i,x,lj,rj,step;
        scanf("%d",&_case);
        while(_case--)
        {
            li.clear();
            scanf("%d",&n);
            for(i=0; i<n; i++)
            {
                scanf("%d",&x);
                li.push_back(x);
            }
            scanf("%d%d",&lj,&rj);
            l=li.begin();
            r=li.begin();
            for(i=1;i<lj;i++)l++;
            for(i=1;i<rj;i++)r++;
            scanf("%d",&step);
            for(i=0; i<step; i++)
            {
                char s[20];
                char c;
                getchar();
                scanf("%s",s);
                if(s[0]=='I')
                {
                    getchar();
                    scanf("%c%d",&c,&x);
                    //puts(c);
                    //printf("%c",c);
                    if(c=='L')// add before,f b
                    {
                        l=li.insert(l,x);
                    }
                    else
                    {
                        r++;
                        r=li.insert(r,x);
                    }
                }
                else if(s[0]=='D')
                {
                    getchar();
                    scanf("%c",&c);
                    if(c=='R')
                    {
                        r=li.erase(r);
                        if(r==li.end()&&r!=li.begin())r--;
                    }
                    else
                    {
                        l=li.erase(l);
                        //if(l==li.end()&&l!=li.begin())l--;
                    }
                }
                else if(s[0]=='R')
                {
                    if(r!=li.end())r++;
                    reverse(l,r);
                    r--;
                }
                else
                {
                    getchar();
                    scanf("%c",&c);
                    if(s[4]=='L')
                    {
    
                        if(c=='L')
                        {
                            if(l!=li.begin())l--;
                        }
                        else
                        {
                            if(r!=li.begin())r--;
                            //printf("%%
    ");
                        }
                    }
                    else
                    {
                        if(c=='L')
                        {
                            if(l!=li.end())l++;
                        }
                        else
                        {
                            if(r!=li.end())r++;
                        }
                    }
                }
                //cout<<*l<<' '<<*r<<endl;
    
            }
            it=li.begin();
            printf("%d",*it);
            it++;
            for(; it!=li.end(); it++)
                printf(" %d",*it);
            printf("
    ");
        }
    
        return 0;
    }
    View Code
     

    数组模拟双向链表:

    自己写的戳:

    #include<stdio.h>
    #define Max 1001000
    struct node
    {
        int fr;//front
        int be;//behind
        int val;//value
        bool flag;
    } num[Max];;
    //int
    int n,m,l,r,x;
    void Moveleft(char c)
    {
        if(c=='L'&&num[l].fr!=0)
            l=num[l].fr;
        else
            r=num[r].fr;
    }
    
    void Moveright(char c)
    {
        if(c=='R'&&num[r].be!=n+1)
            r=num[r].be;
        else
            l=num[l].be;
    }
    void InsertL()
    {
        num[++n].val=x;
        num[n].flag=0;
        num[n].fr=num[l].fr;
        num[n].be=l;
        num[num[l].fr].be=n;
        num[l].fr=n;
    
        l=n;//turn left;
    }
    void InsertR()
    {
        printf("##");
        num[++n].val=x;
        num[n].flag=0;
        num[n].fr=r;
        num[n].be=num[r].be;
    
        num[num[r].be].fr=n;
        num[r].be=n;
        r=n;
    }
    void DeleteL()
    {
        num[num[l].fr].be=num[l].be;
        num[num[l].be].fr=num[l].fr;
        l=num[l].be;
    }
    void DeleteR()
    {
        num[num[r].fr].be=num[l].be;
        num[num[r].be].fr=num[l].fr;
        r=num[r].fr;
    }
    void Reverse()
    {
    
        num[r].flag=1;
        //
        num[num[l].fr].be=r;
        num[num[r].be].fr=l;//num[l].fr;
        int x=num[l].fr;
        num[l].fr=num[r].be;
        num[r].be=x;
    
        num[num[l].fr].flag=l;
    
        //num[num[r].fr].flag=1;
        //num[r].be=num[r],fr;
    }
    void Myprintf()
    {
        printf("##%d%d
    ",l,r);
        int ret=0;
        int x=0;
        x=num[x].be;
        if(x!=m)printf("%d",num[x].val);
        ret^=num[x].flag;
            if(!ret)//equal 0
                x=num[x].be;
            else
                x=num[x].fr;
    
    
        while(x!=m)
        {
    
    
            printf(" %d",num[x].val);
    
            if(!ret)//equal 0
                x=num[x].be;
            else
                x=num[x].fr;
            ret^=num[x].flag;
            //printf("
    $%d$
    ",ret);
        }
        printf("
    ");
    }
    int main()
    {
        int _case,step;
        int i;
        scanf("%d",&_case);
        while(_case--)
        {
            scanf("%d",&n);
            num[0].be=1;
            for(i=1; i<=n; i++)
            {
                scanf("%d",&num[i].val);
                num[i].fr=i-1;
                num[i].be=i+1;
                num[i].flag=0;
            }
            m=++n;
            scanf("%d %d",&l,&r);
            scanf("%d",&step);
            Myprintf();
            while(step--)
            {
                char op[20],loc[20];
                scanf("%s",op);
                if(op[0]=='R')//reverse
                    Reverse();
                else if(op[0]=='I')//insert
                {
                    scanf("%s %d",loc,&x);
                    if(loc[0]=='R')
                        InsertR();
                    else
                        InsertL();
                }
                else if(op[0]=='D')//delete
                {
                    scanf("%s",loc);
                    if(loc[0]=='R')
                        DeleteR();
                    else
                        DeleteL();
                }
                else//Move
                {
                    scanf("%s",loc);
                    if(op[4]=='R')
                        Moveright(loc[0]);
                    else
                        Moveleft(loc[0]);
                }
                Myprintf();
            }
            Myprintf();
        }
        return 0;
    }
    View Code

    参考代码(高明之处 运用了四个左右指针,判断相对位置):

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    
    struct node
    {
        int n1,n2,key;
    };
    
    node a[1000005];
    int L,R,e,n,C,Q,fL,fR;
    
    void init()
    {
        scanf("%d",&n);
        int i;
        for(i=1; i<=n; i++)
        {
            scanf("%d",&a[i].key);
            a[i].n1=i-1;
            a[i].n2=i+1;
        }
        a[0].n2=1;
        a[n+1].n1=n;
        e=n+2;
        scanf("%d%d",&L,&R);
        fL=a[L].n1;
        fR=a[R].n2;
    }
    
    void moveLeftL()
    {
        if(a[fL].n1==L) L=fL,fL=a[fL].n2;
        else L=fL,fL=a[fL].n1;
    }
    
    void moveLeftR()
    {
        if(a[R].n1==fR) fR=R,R=a[R].n2;
        else fR=R,R=a[R].n1;
    }
    
    void moveRightL()
    {
        if(a[L].n1==fL) fL=L,L=a[L].n2;
        else fL=L,L=a[L].n1;
    }
    
    void moveRightR()
    {
        if(a[fR].n1==R) R=fR,fR=a[fR].n2;
        else R=fR,fR=a[fR].n1;
    }
    
    
    void insertL(int x)
    {
        a[e].key=x;
        a[e].n1=fL;
        a[e].n2=L;
        if(a[fL].n1==L) a[fL].n1=e;
        else a[fL].n2=e;
        if(a[L].n1==fL) a[L].n1=e;
        else a[L].n2=e;
        L=e++;
    }
    
    
    void insertR(int x)
    {
        a[e].key=x;
        a[e].n1=R;
        a[e].n2=fR;
        if(a[R].n1==fR) a[R].n1=e;
        else a[R].n2=e;
        if(a[fR].n1==R) a[fR].n1=e;
        else a[fR].n2=e;
        R=e++;
    }
    
    void deleteL()
    {
        int next;
        if(a[L].n1==fL) next=a[L].n2;
        else next=a[L].n1;
        if(a[fL].n1==L) a[fL].n1=next;
        else a[fL].n2=next;
        if(a[next].n1==L) a[next].n1=fL;
        else a[next].n2=fL;
        L=next;
    }
    
    void deleteR()
    {
        int next;
        if(a[R].n1==fR) next=a[R].n2;
        else next=a[R].n1;
        if(a[fR].n1==R) a[fR].n1=next;
        else a[fR].n2=next;
        if(a[next].n1==R) a[next].n1=fR;
        else a[next].n2=fR;
        R=next;
    }
    
    void reverse()
    {
        if(a[fL].n1==L) a[fL].n1=R;
        else a[fL].n2=R;
        if(a[L].n1==fL) a[L].n1=fR;
        else a[L].n2=fR;
        if(a[R].n1==fR) a[R].n1=fL;
        else a[R].n2=fL;
        if(a[fR].n1==R) a[fR].n1=L;
        else a[fR].n2=L;
    
        int k;
        k=L;
        L=R;
        R=k;
    }
    
    void print()
    {
        bool tag=false;
        fL=0;
        L=a[fL].n2;
        while(L!=n+1)
        {
            if(tag) putchar(' ');
            else tag=true;
            printf("%d",a[L].key);
            if(a[L].n1==fL) fL=L,L=a[L].n2;
            else fL=L,L=a[L].n1;
        }
        puts("");
    }
    
    int main()
    {
        for(scanf("%d",&C); C--;)
        {
            init();
            scanf("%d",&Q);
            char op[20],s[20];
            int X;
            while(Q--)
            {
                scanf("%s",op);
                if(!strcmp(op,"MoveLeft"))
                {
                    scanf("%s",s);
                    if(s[0]=='L') moveLeftL();
                    else moveLeftR();
                }
                else if(!strcmp(op,"MoveRight"))
                {
                    scanf("%s",s);
                    if(s[0]=='L') moveRightL();
                    else moveRightR();
                }
                else if(!strcmp(op,"Insert"))
                {
                    scanf("%s%d",s,&X);
                    if(s[0]=='L') insertL(X);
                    else insertR(X);
                }
                else if(!strcmp(op,"Delete"))
                {
                    scanf("%s",s);
                    if(s[0]=='L') deleteL();
                    else deleteR();
                }
                else reverse();
            }
            print();
        }
        return 0;
    }
  • 相关阅读:
    Apache 配置多站点访问「为项目分配二级域名」
    php封装的mysqli类完整实例
    PHP实现链式操作的三种方法详解
    php实现简单链式操作mysql数据库类
    PHP PDO_MYSQL 链式操作 非链式操作类
    23个数据库常用查询语句
    微信小程序表单弹窗实例
    ES6 && ECMAScript2015 新特性
    ES6新语法概览
    sql将两个日期之间的日子全列出来
  • 原文地址:https://www.cnblogs.com/XDJjy/p/3344755.html
Copyright © 2011-2022 走看看