csu1329 一個盒子

Description

你有一行盒子,從左到右依次編號爲1, 2, 3,…, n。你可以執行四種指令:

1 X Y表示把盒子X移動到盒子Y左邊(如果X已經在Y的左邊則忽略此指令)。
2 X Y表示把盒子X移動到盒子Y右邊(如果X已經在Y的右邊則忽略此指令)。
3 X Y表示交換盒子X和Y的位置。
4 表示反轉整條鏈。

指令保證合法,即X不等於Y。例如,當n=6時在初始狀態下執行1 1 4後,盒子序列爲2 3 1 4 5 6。接下來執行2 3 5,盒子序列變成2 1 4 5 3 6。再執行3 1 6,得到2 6 4 5 3 1。最終執行4,得到1 3 5 4 6 2。

Input

輸入包含不超過10組數據,每組數據第一行爲盒子個數n和指令條數m(1<=n,m<=100,000),以下m行每行包含一條指令。

Output

每組數據輸出一行,即所有奇數位置的盒子編號之和。位置從左到右編號爲1~n。

Sample Input

6 41 1 42 3 53 1 646 31 1 42 3 53 1 6100000 14

Sample Output

Case 1: 12Case 2: 9Case 3: 2500050000

Hint

Source

湖南省第九屆大學生計算機程序設計競賽


思路:
這個題拿到腦子裏應該會想到用鏈表,因爲方便插入刪除,不用像數組那麼複雜。
可是難點在於把整個串反轉的時候需要會不會TE.
處理方法很巧妙:
我們用數組模擬鏈表(你也可以鏈表一個*next指向下一個,一個*previous指向上一個),我採用l,r來指向左右單元的數。
其實每次移動不用把數組裏的單元格移動,只需要改變單元格的l,r就可以達到同樣的效果。
如4個盒子
    0       1        2         3          4
-1     1 0    2  1     3 2     4  3       5(l,r)
把1移動到4左邊,則變爲
     0      1        2         3           4
-1     23     4 0     3   2    1   1      5
另外需要注意的是,進行3操作時,我們需要注意。具體見代碼註釋。、
還有進行四操作時,並不需要把整個串反過來,只要要反着進行1,2操作就行,就像正着來插入在左邊,反着來就插入在右邊。判斷出現次數奇偶就行。
#include<stdio.h>
#include<iostream>
#include<cstring>
using namespace std;
struct node
{
    int l,r;
}box[100005];
/*int cmp(box a,box b)
{
    return a.l<b.l;
}*/
int main()
{
    int n,m,flag,cnt=0;
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        //cnt=0;
        flag=0;
        for(int i=0;i<=n;i++)
        {
            box[i].l=i-1;
            box[i].r=i+1;
        }
       /* for(int i=0;i<=n;i++)
        {
            cout<<box[i].l<<" "<<box[i].r<<endl;
        }*/
        int a,b,c;
        for(int i=0;i<m;i++)
        {
            scanf("%d",&a);
            //
            //cout<<"-----------"<<endl;
            if(a==4) flag^=1;//異或操作,看出現四操作次數爲奇數還是偶數
            else
            {
                scanf("%d %d",&b,&c);
               if(a==3){ //注意3的交換操作
                    int tmp;
                    if(box[b].l==c)//注意不要出現自己的左邊或右邊爲自己的請況
                    {
                        box[box[b].r].l=c;  box[box[c].l].r=b;
                        box[b].l = box[c].l; box[c].l=b;
                        box[c].r = box[b].r; box[b].r=c;
                    }
                    else if(box[c].l==b){//與上同理
                        box[box[c].r].l=b;  box[box[b].l].r=c;
                        box[c].l = box[b].l; box[b].l=c;
                        box[b].r = box[c].r; box[c].r=b;
                    }
                    else{//一般情況
                        box[box[b].l].r= c ; box[box[b].r].l = c;
                        box[box[c].l].r= b ; box[box[c].r].l = b;
                        tmp = box[b].l ; box[b].l=box[c].l; box[c].l=tmp;
                        tmp = box[b].r ; box[b].r=box[c].r; box[c].r=tmp;
                    }
                    continue ;
                }
                if(flag) a=3-a;
                if(a==1)///b移動到c左邊
                {
                    if(box[b].r==c&&box[c].l==b) continue;
                    box[box[b].l].r=box[b].r;
                    box[box[b].r].l=box[b].l;

                    box[b].l=box[c].l;
                    box[b].r=box[box[c].l].r;
                    box[box[c].l].r=b;
                    box[c].l=b;

                }
                else if(a==2)///b移動到c右邊
                {
                    if(box[c].r==b&&box[b].l==c) continue;
                    box[box[b].l].r=box[b].r;
                    box[box[b].r].l=box[b].l;
                    box[b].r=box[c].r;
                    box[b].l=c;
                    box[box[c].r].l=b;
                    box[c].r=b;
                }
            }

        }
       /* for(int i=0;i<=n;i++)
            {
            cout<<box[i].l<<" "<<box[i].r<<endl;
            }*/
        int kk=1;int ans;

        long long sum=0;
        if(flag)
        {
             ans=box[0].r;
             while(kk<=n)
            {
                //cout<<ans<<" "<<kk<<"\\\';
               if(!(kk&1))
               {// cout<<ans<<endl;
                   sum+=ans;
                   //cout<<sum<<endl;
                   //cout<<ans<<" ";
               }

                ans=box[ans].r;
                kk++;
            }
        }
        else
        {
            ans=box[0].r;
            while(kk<=n)
            {
                //cout<<ans<<" ";
                if(kk&1)
               sum+=ans;
                ans=box[ans].r;
                kk++;
            }
        }

        //cout<<endl;
       printf("Case %d: %lld\n",++cnt,sum);
    }
    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章