zoukankan      html  css  js  c++  java
  • CSUOJ1329——一行盒子_湖南省第九届大学生计算机程序设计竞赛

    题目是中文的我就不是说明了,比赛的时候看过题目后队友说是splay来做,细想来省赛不会出这么坑的题目吧。

    于是比赛还有一个小时左右把该做的都做完了以后,我们队三个人都来思考这个题目了。不过还好很快我们就跳过了这个splay的坑。

    因为这个题目根本不是spaly,直接用数组模拟链表就行了,所有的操作都可以再O(1)的时间复杂度以内搞定。

    可以这样做,首先对于每一个数,我们都可以视为一个节点,然后一条链的话就相当于是指针操作了,每个节点都设置两个指针——前驱和后继。

    设置后继节点是为了应对4操作,因为全部取反只要交换后继和前驱就可以了(其实不用交换也行,只要记录总共要交换多少次就行了,因为换两次就换回来了哦)

    对于1、2、3就是简单的链表操作了,不过注意3操作有一个坑,就是x和y可能是相邻的两个节点哦,特别注意了,这里有点坑的。

    不过说了,上代码,这个题目时间虽然是O(n),但是时间还不算宽哦,所以写的时候还是注意一下比较好。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #define maxn 1001000
     5 #define ll long long
     6 using namespace std;
     7  
     8 int next[maxn],pre[maxn],n,m,k,tim;
     9 int *tep,*tep2;
    10  
    11 void init_next_pre()
    12 {
    13     for (int i=1; i<=n; i++) next[i]=i+1,pre[i]=i-1;
    14     next[n]=0;
    15 }
    16  
    17 void dele(int x)
    18 {
    19     int k1=pre[x],k2=next[x];
    20     next[k1]=k2,pre[k2]=k1;
    21 }
    22  
    23 void insert(int k1,int mid,int k2)
    24 {
    25     next[k1]=mid,next[mid]=k2;
    26     pre[k2]=mid,pre[mid]=k1;
    27 }
    28  
    29 void SWAP(int x,int y)
    30 {
    31     int k1=pre[x],k2=next[x],k3=pre[y],k4=next[y];
    32     if (k2==y)//考虑xy相邻的情况
    33     {
    34         next[k1]=y,next[y]=x,next[x]=k4;
    35         pre[k4]=x,pre[x]=y,pre[y]=k1;
    36     }
    37     else if (k4==x)//考虑xy相邻的情况
    38     {
    39         next[k3]=x,next[x]=y,next[y]=k2;
    40         pre[k2]=y,pre[y]=x,pre[x]=k3;
    41     }
    42     else
    43     {
    44         next[k1]=y,next[y]=k2,pre[y]=k1,pre[k2]=y;
    45         next[k3]=x,next[x]=k4,pre[x]=k3,pre[k4]=x;
    46     }
    47 }
    48  
    49 int main()
    50 {
    51     int cod,x,y,cas=0;
    52     while (cin>>n>>m)
    53     {
    54         tim=0;
    55         init_next_pre();
    56         while (m--)
    57         {
    58             cin>>cod;
    59             if (cod==4) tim++;//这里只要记录首位交换了多少次哦
    60             else
    61             {
    62                 cin>>x>>y;
    63                 if (cod<3 && tim&1) cod=3-cod;//如果交换了奇数次,那么本来应该插在前面就相当于是现在应该插在后面,T_T不好怎么表达,自己理解一下就懂了。
    64                 if (cod==1)
    65                 {
    66                     dele(x);
    67                     k=pre[y];
    68                     insert(k,x,y);
    69                 }
    70                 else if (cod==2)
    71                 {
    72                     dele(x);
    73                     k=next[y];
    74                     insert(y,x,k);
    75                 }
    76                 else if (cod==3) SWAP(x,y);
    77             }
    78         }
    79         if (tim&1) tep=pre,tep2=next; else tep=next,tep2=pre;
    80         for (int i=1; i<=n; i++)
    81         {
    82             if (tep2[i]==0)
    83             {
    84                 ll ans=0;
    85                 for (int k=1; i; i=tep[i],k++) if (k&1) ans+=i;
    86                 cout<<"Case "<<++cas<<": "<<ans<<endl;
    87                 break;
    88             }
    89         }
    90     }
    91     return 0;
    92 }
    如有转载,请注明出处(http://www.cnblogs.com/lochan)
  • 相关阅读:
    http
    jquery
    wsgi
    urls控制器
    模板template
    ORM
    C++中获取汉字拼音首字缩写/全拼及生僻字的处理
    C语言函数strstr
    CString 成员函数用法
    判断字符串中是否存在中文
  • 原文地址:https://www.cnblogs.com/lochan/p/3371208.html
Copyright © 2011-2022 走看看