UVA 12657 链表模拟

来源:互联网 发布:付费网络推广方式 编辑:程序博客网 时间:2024/06/03 08:35
You have n boxes in a line on the table numbered 1. . . n from left to right. Your task is to simulate 4
kinds of commands:
• 1 X Y : move box X to the left to Y (ignore this if X is already the left of Y )
• 2 X Y : move box X to the right to Y (ignore this if X is already the right of Y )
• 3 X Y : swap box X and Y
• 4: reverse the whole line.
Commands are guaranteed to be valid, i.e. X will be not equal to Y .
For example, if n = 6, after executing 1 1 4, the line becomes 2 3 1 4 5 6. Then after executing
2 3 5, the line becomes 2 1 4 5 3 6. Then after executing 3 1 6, the line becomes 2 6 4 5 3 1.
Then after executing 4, then line becomes 1 3 5 4 6 2
Input
There will be at most 10 test cases. Each test case begins with a line containing 2 integers n, m
(1 ≤ n, m ≤ 100,000). Each of the following m lines contain a command.
Output
For each test case, print the sum of numbers at odd-indexed positions. Positions are numbered 1 to n
from left to right.
Sample Input
6 4
1 1 4
2 3 5
3 1 6
4
6 3
1 1 4
2 3 5
3 1 6
100000 1
4
Sample Output
Case 1: 12
Case 2: 9

Case 3: 2500050000


题意:给你1~n个箱子,每个箱子的价值为1~n,进行m次操作,共有四种类型的操作,

1 x y表示把x放在y的左端;

2 x y 表示把x放在y的右端;;

3 x y表示把x和y互换位置;

4 表示把全部箱子的位置倒转过来

问你在m次操作之后,奇数位置的箱子价值总和为多少。


从插入等操作,可以看出这道题是链表问题,用STL的链表尝试,发现超时了,最终用数组模拟链表A了这道题。

可以看出STL的链表比自己写的链表速度要慢。

以下是超时代码:

#include<cstdio>#include<iostream>#include<cstring>#include<list>#include<algorithm>using namespace std;list<int>l;list<int>::iterator it1,it2,it;void solve(int a,int a1=1,int a2=1){    if(a==4){l.reverse();return ;}    if(a1==a2)return ;    it1=find(l.begin(),l.end(),a1);    it2=find(l.begin(),l.end(),a2);    if(a==1){        l.erase(it1);        l.insert(it2,a1);    }    if(a==2){        l.erase(it1);        l.insert(++it2,a1);    }    if(a==3){        l.insert(it2,a1);        l.insert(it1,a2);        l.erase(it1);        l.erase(it2);    }}int main(){    int m,n,flag,x,y,Case=1;    while(~scanf("%d%d",&n,&m)){        l.clear();        for(int i=1;i<=n;i++){            l.push_back(i);        }        for(int i=0;i<m;i++){            scanf("%d",&flag);            if(flag==4){                solve(flag);            }            else{                scanf("%d%d",&x,&y);                solve(flag,x,y);            }        }        long long ans=0;        for(it=l.begin();it!=l.end();++it){            ans+=*it;            if(++it==l.end())break;        }        printf("Case %d: %I64d\n",Case++,ans);    }    return 0;}

数组模拟双向链表操作的代码:

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;const int maxn = 100010;int l[maxn],r[maxn];void unlink(int p1){    int t1=l[p1];    int t2=r[p1];    r[t1]=t2;    l[t2]=t1;}void link(int p1,int p2,int v){    r[p1]=v;    r[v]=p2;    l[p2]=v;    l[v]=p1;}int main(){    int n,m;    int a,b,c;    int Case = 1;    while(~scanf("%d%d",&n,&m)){        memset(r,0,sizeof(r));        memset(l,0,sizeof(l));        for(int i=1;i<=n;i++){            r[i]=(i+1)%(n+1);            l[i]=i-1;        }        r[0]=1;        l[0]=n;        bool flag=true;        for(int i=0;i<m;i++){            scanf("%d",&a);            if(a==4){flag=!flag;continue;};            scanf("%d%d",&b,&c);            if(a==1){                if(b==l[c])continue;                unlink(b);                if(flag)link(l[c],c,b);                else link(c,r[c],b);            }            if(a==2){                if(b==r[c])continue;                unlink(b);                if(flag) link(c,r[c],b);                else link(l[c],c,b);            }            if(a==3){                if(r[b]==c){                    int t1=l[b];                    int t2=r[c];                    l[b]=c;                    r[c]=b;                    l[c]=t1;                    r[b]=t2;                    r[t1]=c;                    l[t2]=b;                }                else if(l[b]==c){                    int t1=l[c];                    int t2=r[b];                    l[c]=b;                    r[b]=c;                    l[b]=t1;                    r[c]=t2;                    r[t1]=b;                    l[t2]=c;                }                else{                    unlink(b);                    unlink(c);                    int t1=l[c];                    int t2=r[c];                    link(l[b],r[b],c);                    link(t1,t2,b);                }            }        }        long long ans=0;        if(flag){            bool flag1=true;            for(int i=r[0];i!=0;i=r[i]){                if(flag1){                    ans+=i;                }                flag1=!flag1;            }        }        else{            bool flag1=true;            for(int i=l[0];i!=0;i=l[i]){                if(flag1)ans+=i;                flag1=!flag1;            }        }        printf("Case %d: %lld\n",Case++,ans);    }    return 0;}



1 0
原创粉丝点击