uva 12657 - Boxes in a Line(AC和TLE的区别,为什么说STL慢..)

用STL中的list写的,TLE

#include<cstdio>
#include<iostream>
#include<cstring>
#include<list>
#include<algorithm>
using namespace std;

list<int> l;
list<int>::iterator it1,it2,it3,it4,it5,it;

void work(int a,int a1=1,int a2=1)
{

    it1=find(l.begin(),l.end(),a1);
    it2=find(l.begin(),l.end(),a2);
    it3=find(l.begin(),l.end(),a2);
    it4=find(l.begin(),l.end(),a1);
    it5=find(l.begin(),l.end(),a2);
    if(a==1)
    {
        if(*it4++==a2) return;
        l.erase(it1);
        l.insert(it2,a1);
    }
    if(a==2)
    {
        if(*it5++==a1) return;
        l.erase(it1);
        l.insert(++it3,a1);
    }
    if(a==3)
    {
        l.insert(it2,a1);
        l.insert(it1,a2);
        l.erase(it1);
        l.erase(it2);
    }
    if(a==4)
    {
        l.reverse();
    }
}

int main()
{
    int m,n;
    int kk,x,y;
    int kase=0;
    while(cin>>n>>m)
    {
        kase++;
        l.clear();
        for(int i=1; i<=n; i++)
            l.push_back(i);
        for(int i=0;i<m;i++)
        {
            cin>>kk;
            if(kk==4)
                work(kk);
            else
            {
                cin>>x>>y;
                work(kk,x,y);
            }
        }
        bool flag=true;
        long long ans=0;
        for(it=l.begin(); it!=l.end(); ++it)
        {
            if(flag)
            {
                ans+=*it;
            }
            flag=!flag;
        }
        cout<<"Case "<<kase<<": "<<ans<<endl;
    }
    return 0;
}

AC代码,用数组模拟链表:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

const int maxn = 100010;
int next[maxn],prev[maxn];

void unlink(int pos1)
{
    int temp1 = prev[pos1];
    int temp2 = next[pos1];
    next[temp1]=temp2;
    prev[temp2]=temp1;

}
void link(int pos1,int pos2,int aa)
{
    next[pos1]=aa;
    next[aa]=pos2;
    prev[pos2]=aa;
    prev[aa]=pos1;
}
int main()
{
    int n,m;
    int a,b,c;
    int kase=0;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        kase++;
        memset(next,0,sizeof(next));
        memset(prev,0,sizeof(prev));
        for(int i=1; i<=n; i++)
        {
            next[i]=(i+1)%(n+1);
            prev[i]=(i-1);
        }
        next[0]=1;
        prev[0]=n;
        bool flag=true;
        for(int i=0; i<m; i++)
        {
            scanf("%d",&a);
            if(a==1)
            {
                scanf("%d%d",&b,&c);
                if(b==prev[c]) continue;
                unlink(b);
                if(flag)
                    link(prev[c],c,b);
                else
                    link(c,next[c],b);
            }
            if(a==2)
            {
                scanf("%d%d",&b,&c);
                if(b==next[c]) continue;
                unlink(b);
                if(flag)
                    link(c,next[c],b);
                else
                    link(prev[c],c,b);
            }
            if(a==3)
            {
                scanf("%d%d",&b,&c);
                if(next[b]==c)
                {
                    int temp1=prev[b];
                    int temp2=next[c];
                    prev[b]=c;
                    next[c]=b;
                    prev[c]=temp1;
                    next[b]=temp2;
                    next[temp1]=c;
                    prev[temp2]=b;
                }
                else if(prev[b]==c)
                {
                    int temp1=prev[c];
                    int temp2=next[b];
                    prev[c]=b;
                    next[b]=c;
                    prev[b]=temp1;
                    next[c]=temp2;
                    next[temp1]=b;
                    prev[temp2]=c;
                }
                else
                {
                    unlink(b);
                    unlink(c);
                    int temp1=prev[c];
                    int temp2=next[c];
                    link(prev[b],next[b],c);
                    link(temp1,temp2,b);
                }
            }
            if(a==4)
            {
                flag=!flag;
            }
        }
        long long ans=0;
        if(flag)
        {
            bool flag1=true;
            for(int i=next[0]; i!=0; i=next[i])
            {
                if(flag1)
                {
                    ans+=i;
                }
                flag1=!flag1;
            }
        }
        else
        {
            bool flag1=true;
            for(int i=prev[0]; i!=0; i=prev[i])
            {
                if(flag1)
                {
                    ans+=i;
                }
                flag1=!flag1;
            }
        }
        cout<<"Case "<<kase<<": "<<ans<<endl;
    }
    return 0;
}

STL虽然方便,但是确实慢了许多。用的时候须谨慎...

uva 12657 - Boxes in a Line(AC和TLE的区别,为什么说STL慢..),布布扣,bubuko.com

时间: 2024-10-24 22:42:01

uva 12657 - Boxes in a Line(AC和TLE的区别,为什么说STL慢..)的相关文章

UVa 12657 Boxes in a Line(双向链表的应用)

Boxes in a Line 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 th

UVa 12657 Boxes in a Line(应用双链表)

Boxes in a Line 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 th

UVA 12657 Boxes in a Line

题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4395 题目意思是说,给出一个数n,表示存在一个整数序列1--n,然后进行四种操作: 操作一:输入x,y,表示将x移到y的左边(若x本来就在y的左边则忽略): 操作二:输入x,y,表示将x移到y的右边(若x本来就在y的右边则忽略): 操作三:输入x,y,表示交换x和y. 操作四:将

Uva 12657 Boxes in a Line 双向链表

操作4比较特殊,为了避免一次性修改所有元素的指针,由于题目只要求输出奇数盒子的编号,所以我们可以灵活的根据是否进行过操作4对操作1 操作2 进行改动 操作3不受操作4影响 上代码.... #include<cstdio> #include<algorithm> const int maxn=100000+5; int right[maxn],left[maxn]; void link (int L,int R){ right[L]=R;left[R]=L; } //在双向链表这样复

UVA 12657 Boxes in a Line(双向链表+小技巧)

题意:对于一行按照顺序排列盒子数字与位置都为 1,2,3,4....n 执行四种操作 c = 1    x 放到 y 的左边 c =2     x 放到 y 的右边 c =3 交换 x, y c =4 颠倒链 最后求出奇数位置的数的总和 题解:直接维护无论如何每次每次都需要维护一段区间的位置,因此不去看位置.只需要知道每个盒子左边是哪个盒子右边是哪个盒子 这样就直接使用双向链表维护,接着颠倒时注意只是标记就好 最后注意几个细节: 首先颠倒后1与2的交换需要互换: 维护链表时可以提取出一个函数,每

UVa 12657 Boxes in a Line(数组模拟双链表)

题目链接 1 /* 2 问题 3 将一排盒子经过一系列的操作后,计算并输出奇数位置上的盒子标号之和 4 5 解题思路 6 由于数据范围很大,直接数组模拟会超时,所以采用数组模拟的链表,left[i]和right[i]分别表示i号盒子的左边是谁和右边 7 是谁.特别提醒,4这个操作可以采用其他的办法去标记,而不必真的去模拟交换,否则会超时. 8 */ 9 10 #include<cstdio> 11 #include<algorithm> 12 13 using namespace

12657 - Boxes in a Line

Boxes in a Line 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

Uva12657 (Boxes in a Line)移动盒子

UVA 12657 Boxes in a Line You have n boxes in a line on the table numbered 1 . . . n from left to right. Your task is to simulate 4kinds 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

【日常学习】【模拟双向链表】【疑问】Uva12657 - Boxes in a Line题解

这道题目我做的不对.事实上,我按书上的标程抄的,几乎一模一样,我认为他没有什么错误,可我就是不知道为什么我在代码仓库下的刘汝佳写的程序就AC,我写的就WA.跳了一下午,两程序样例输出完全一样(奇怪的是和书上答案不一样)一个字一个字的比对,就是找不出哪里不一样.我觉得极少不一样的地方应该没有影响,哪位大神愿意给看看? 这是一道双向链表,同样没有用指针,而是用两个数组模拟,道理和上面的那道非指针单向链表题目一样 刘汝佳的代码 // UVa12657 Boxes in a Line // Rujia