UVA12657

这道题又是一道适合于练习链表的题目

这道题目中学到的东西有:

果然用数组代替链表编程要简单很多

具体原因可以把next  New front看成是一体的,其实就相当于结构体的数组

双向链表的表示

如果想要逆转链表那么直接将next和front交换一下就可以了

memcopy的使用

链表的输出方式

但是很可惜的是,这样的方式在UVA看来是超时的,所以要想通过所有的case,那么就得使用刘汝佳的方式,将某一个操作记录下来。

下面先贴出超时的版本:

//这道题目刘汝佳的版本是要用一个flag来记录时间消耗比较大的操作,但是这种方法不一定能想到了,我还是先用数组的方式写一遍吧,看看效果怎样
//这种方式果然超时了,看来还是得用刘汝佳的方式啊
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<ctime>
using namespace std;

int New[100000+5];
int Next[100000+5];
int front[100000+5];
int Copy[100000+5];

int num_node,num_comd;
int start,last,kase = 0;

void connect(int a,int b)
{
    *(Next+a) = b;
    *(front+b) = a;
}

void pro(int x)
{
    if(x == 1)
    {
        int a,b;//把a放在b的左面
        scanf("%d%d",&a,&b);
        if(*(Next+a) == b)
            return;
        connect(*(front+a),*(Next+a));
        connect(*(front+b),a);
        connect(a,b);
    }
    if(x == 2)
    {
        int a,b;//把a放在b的右面
        scanf("%d%d",&a,&b);
        if(*(Next+b) == a)
            return;
        connect(*(front+a),*(Next+a));
        connect(a,*(Next+b));
        connect(b,a);
    }
    if(x == 3)
    {
        int a,b;//交换ab
        scanf("%d%d",&a,&b);
        if(*(Next+a) == b)//相邻
        {
            connect(*(front+a),b);
            connect(a,*(Next+b));
            connect(b,a);
        }
        else if(*(Next+b) == a)
        {
            connect(*(front+b),a);
            connect(b,*(Next+a));
            connect(a,b);
        }
        else
        {
            int x1 = *(Next+b),x2 = *(front+b);
            connect(*(front+a),b);
            connect(b,*(Next+a));
            connect(x2,a);
            connect(a,x1);
        }
    }
    if(x == 4)
    {
        int a = last;
        last = start;
        start= a;
        memcpy(Copy,front,sizeof(int)*(num_node+2));
        memcpy(front,Next,sizeof(int)*(num_node+2));
        memcpy(Next,Copy,sizeof(int)*(num_node+2));
    }

}
void initial()
{
    start = 0; last = num_node+1;
    for(int i = 0;i <= num_node+1;i++)
    {
        *(New+i) = i;
        *(Next+i) = i + 1;
        *(front+i) = i - 1;
    }
    //front[num_node+1]=num_node;
    *(Next+num_node+1)=0;
    //New[num_node+1]=num_node+1;
    *(front)=num_node+1;
}

void print_link()
{
    for(int i = *(Next+start);*(New+i) != last;i = *(Next+i))
    {
        printf("%d  ",*(New+i));
    }
    printf("\n");
}
void print_ans()
{
    long long sum = 0;
    for(int i = *(Next+start),num=1;*(New+i) != last;i = *(Next+i),num++)
    {
        if(num % 2 == 1)
        {
            sum = sum + *(New+i);
        }
    }
    cout<<"Case "<<++kase<<": "<<sum<<endl;
}
int main ()
{
#ifdef local
    freopen("input.txt","r",stdin);
    freopen("output1.txt","w",stdout);
#endif
    while(scanf("%d%d",&num_node,&num_comd)==2)
    {
        initial();//初始化数组
//print_link();
        for(int i = 0;i < num_comd;i++)
        {
            int x;
            scanf("%d",&x);
            pro(x);
//print_link();
        }
        print_ans();
    }
    printf("%lf",(double)clock()/CLOCKS_PER_SEC);
    return 0;

}

再贴出我模仿刘汝佳的版本

//这道题目刘汝佳的版本是要用一个flag来记录时间消耗比较大的操作,但是这种方法不一定能想到了,我还是先用数组的方式写一遍吧,看看效果怎样
//这种方式果然超时了,看来还是得用刘汝佳的方式啊
#include<cstdio>
#include<iostream>
#include<string>
#include<cstring>
#include<ctime>
using namespace std;

int New[100000+5];
int Next[100000+5];
int front[100000+5];

int num_node,num_comd;
int start,last,kase = 0;
int turn =0;

void connect(int a,int b)
{
    *(Next+a) = b;
    *(front+b) = a;
}

void pro(int x)
{
    if(turn)
    {
        if(x==1)
            x=2;
        else if(x==2)
            x=1;
    }
    if(x == 1)
    {
        int a,b;//把a放在b的左面
        scanf("%d%d",&a,&b);
        if(*(Next+a) == b)
            return;
        connect(*(front+a),*(Next+a));
        connect(*(front+b),a);
        connect(a,b);
    }
    if(x == 2)
    {
        int a,b;//把a放在b的右面
        scanf("%d%d",&a,&b);
        if(*(Next+b) == a)
            return;
        connect(*(front+a),*(Next+a));
        connect(a,*(Next+b));
        connect(b,a);
    }
    if(x == 3)
    {
        int a,b;//交换ab
        scanf("%d%d",&a,&b);
        if(*(Next+a) == b)//相邻
        {
            connect(*(front+a),b);
            connect(a,*(Next+b));
            connect(b,a);
        }
        else if(*(Next+b) == a)
        {
            connect(*(front+b),a);
            connect(b,*(Next+a));
            connect(a,b);
        }
        else
        {
            int x1 = *(Next+b),x2 = *(front+b);
            connect(*(front+a),b);
            connect(b,*(Next+a));
            connect(x2,a);
            connect(a,x1);
        }
    }
    if(x == 4)
    {
        turn=!turn;
    }

}
void initial()
{
    start = 0; last = num_node+1;
    for(int i = 0;i <= num_node+1;i++)
    {
        *(New+i) = i;
        *(Next+i) = i + 1;
        *(front+i) = i - 1;
    }
    //front[num_node+1]=num_node;
    *(Next+num_node+1)=0;
    //New[num_node+1]=num_node+1;
    *(front)=num_node+1;
}

void print_link()
{
    for(int i = *(Next+start);*(New+i) != last;i = *(Next+i))
    {
        printf("%d  ",*(New+i));
    }
    printf("\n");
}
void print_ans()
{
    long long sum = 0;
    if(!turn||num_node%2==1)
    {
        for(int i = *(Next+start),num=1;*(New+i) != last;i = *(Next+i),num++)
        {
            if(num % 2 == 1)
            {
                sum = sum + *(New+i);
            }
        }
    }
    else
    {
        for(int i = *(Next+start),num=1;*(New+i) != last;i = *(Next+i),num++)
        {
            if(num % 2 == 0)
            {
                sum = sum + *(New+i);
            }
        }

    }
    cout<<"Case "<<++kase<<": "<<sum<<endl;
}
int main ()
{
#ifdef local
    freopen("input.txt","r",stdin);
    freopen("output1.txt","w",stdout);
#endif
    while(scanf("%d%d",&num_node,&num_comd)==2)
    {
        turn = 0;
        initial();//初始化数组
//print_link();
        for(int i = 0;i < num_comd;i++)
        {
            int x;
            scanf("%d",&x);
            pro(x);
//print_link();
        }
        print_ans();
    }
    //printf("%lf",(double)clock()/CLOCKS_PER_SEC);
    return 0;

}

首先如果要使用这种方式,那么第一步应该做的是将上一个容易超时的写出来,成功之后再使用第二种,之后还需要对拍。

这道题犯过的错误是两个if写在了一起

以后绝对不能出现这种情况,两个if写在一起和if else 在想要实现的功能上是完全没有区别的。

猜你喜欢

转载自www.cnblogs.com/TorettoRui/p/10427810.html
今日推荐