首页 > 代码库 > UVA101

UVA101

move a onto b  将a和b上的所有的积木放回原始位置,然后将a放到b上面
move a over b  将a放在包含b的栈顶,将a上所有的积木放回原处
pile a onto b  先将b上的积木放回原处,将a和a上面的积木放在b的上面,
pile a over b  将a和a上面的积木放在包含b的堆上

//数组保存列表头

#include <iostream>
#include<stdio.h>
using namespace std;


struct Node
{
    int i;
    int oi;
    struct Node* next;
    struct Node* pre;
};
Node* findNode(Node* node,const int a);
Node* findLastNode(Node*  aNode);
void backAllNextNode(Node* node, Node* aNode);
void updateNextNodeHead(Node* const node,Node*  aNode);

void init(const int n,Node* const node)
{
    for(int i = 0; i < n; i++)
    {
        struct Node n;
        n.i = i;
        n.oi = i;
        n.next = NULL;
        n.pre = NULL;
        *(node+i) = n;
    }
}

void printList(Node * node)
{
    while(node!=NULL)
    {
        cout<<" "<<node->oi;
        node = node->next;
    }
}

void print(Node* const node,const int n)
{
    for(int i = 0; i < n; i++)
    {
        cout<<i<<":";
        if(node[i].i == i)
        {
            //是一个列表
            printList(node+i);
        }
        cout<<endl;

    }

}






void moveOnto(Node* const node,int const a,int const b)
{
    if(node[a].i == node[b].i)
    {
        return;
    }
    Node* aNode = findNode(node,a);
    Node* bNode = findNode(node,b);
    if(aNode->pre!=NULL)
    {
        aNode->pre->next = NULL;
        aNode->pre = NULL;
    }

    backAllNextNode(node,aNode);
    backAllNextNode(node,bNode);
    //a放在b后
    bNode->next = aNode;
    aNode->pre = bNode;
    aNode->i = node[b].i;
}


void moveOver(Node* const node,const int  a,const int b)
{
    if(node[a].i == node[b].i)
    {
        return;
    }
    Node* aNode = findNode(node,a);
    if(aNode->pre != NULL)
    {
        aNode->pre->next = NULL;
        aNode->pre = NULL;
    }
    backAllNextNode(node,aNode);
    Node* bHeadNode = node+b;
    node[a].i = bHeadNode->i;
    Node* lastNode = findLastNode(bHeadNode);
    lastNode->next = aNode;
    aNode->pre = lastNode;
}

void pileOnto(Node* const node,const int a,const int b)
{
    if(node[a].i == node[b].i)
    {
        return;
    }
    Node* bNode = findNode(node,b);
    backAllNextNode(node,bNode);
    Node* aNode = findNode(node,a);
    if(aNode->pre!=NULL)
    {
        aNode->pre->next = NULL;
        aNode->pre = NULL;
    }
    //将a后面的列放在b的后面
    node[a].i = node[b].i;
    aNode->pre = bNode;
    bNode->next = aNode;
    //需要将a后面节点的头更新成b的节点头
    updateNextNodeHead(node,aNode);
}


void pileOver(Node* const node,const int a,const int b)
{
    if(node[a].i == node[b].i)
    {
        return;
    }
    Node* aNode = findNode(node,a);
    Node* lastNode = findLastNode(node+b);
    if(aNode->pre!=NULL)
    {
        aNode->pre->next = NULL;
        aNode->pre = NULL;
    }
    node[a].i = node[b].i;
    aNode->pre = lastNode;
    lastNode->next = aNode;
    updateNextNodeHead(node,aNode);
}


int main()
{
    //freopen("d:\\1.txt","r",stdin);
    int n;
    while(cin>>n)
    {
        Node* node = new Node[n+1];
        init(n,node);
        int a,b;
        string op,w;
        while(cin)
        {
            cin>>op;
            if(op=="quit")
            {
                break;
            }
            cin>>a>>w>>b;
            if(op=="move")
            {
                if(w=="onto")
                {
                    moveOnto(node,a,b);
                }
                else if(w=="over")
                {
                    moveOver(node,a,b);
                }
            }
            else if(op=="pile")
            {
                if(w=="onto")
                {
                    pileOnto(node,a,b);
                }
                else if(w=="over")
                {
                    pileOver(node,a,b);
                }
            }

        }
        print(node,n);
    }
    return 0;
}



Node* findNode(Node* node,const int a)
{
    return node+a;
}

Node* findLastNode(Node*  aNode)
{
    Node* sNode = aNode;
    while(sNode->next!=NULL)
    {
        sNode=sNode->next;
    }
    return sNode;
}

/**
*将aNode后面的节点返回原处,并断开联系
*/
void backAllNextNode(Node* node, Node* aNode)
{
    Node* nextNode;
    while(aNode->next!=NULL)
    {
        nextNode = aNode->next;
        aNode->next = NULL;
        nextNode->pre = NULL;

        aNode = nextNode;
        node[nextNode->oi].i = nextNode->oi;
    }
}

void updateNextNodeHead(Node* const node,Node*  aNode)
{
    Node* newHead = aNode;
    while(aNode->next!=NULL)
    {
        aNode->next->i = newHead->i;
        aNode = aNode->next;
    }
}

  

UVA101