实验一——Dr.Kong设计了一件艺术品(线性表的使用)

[问题描述]

Dr.Kong设计了一件艺术品,该艺术品由N个构件堆叠而成,N个构件从高到低按层编号依次为1,2,……,N。艺术品展出后,引起了强烈的反映。Dr.Kong观察到,人们尤其对作品的高端部分评价甚多。

狂热的Dr.Kong一激动,对组成该艺术品的N个构件重新组合,比如:把第6层到第12层的构件搬下来,想一想,然后整体放到剩下构件的第7层下面;过一会儿,又把第2层到第9层的构件搬下来,整体放到剩下构件的第1层下面等等。于是,Dr.Kong在进行了连续若干次“搬来搬去”后,还是这N个构件,又诞生了一件新的艺术品。

编程:请输出新的艺术品最高十层构件的编号。

标准输入

第一行: N K       表示构件的总数和“搬来搬去”的总次数

第2~K+1行:A B C    表示要搬动的构件(即从第A层到第B层)整个放在第C层下面;

如果C等于0,则要搬动的构件将放到最高层。

标准输出

由十行组成,分别为组成新艺术品的第一层到第十层构件的编号。

约束条件

(1)   10≤N≤20000    1≤k≤1000

(2)   1≤A≤B≤N,      0≤C≤N-(B-A+1)

【 样  例 】

提示:样例中仅是常规的测试数据输入及对应结果,特殊情况需要全面考虑,自己设计测试数据验证算法的健壮性。

标准输入(测试数据):

13 3

6 12 1

2 9 0

10 13 8

标准输出结果:

6

7

8

9

10

11

12

2

3

4

[实现提示]
  适宜于用带表头结点的单链表实现,涉及单个结点或连续多个结点的插入与删除。

主要思想:

将n个艺术品看成长度为n的链表。创建一个带头结点的单链表,使用“前插法”将编号存储在每个结点的数据域里。保存断开链中第一个结点,第一个结点的前一个结点的位置,最后一个结点的位置以及保存将要插入结点处的位置。运用插入知识将各个结点连接起来。对于要插入处为头结点处的情况,直接将头指针保存下来。最后将前10个编号输出。

调试分析:

1、曾在初始化时将p的指向搞错,对于指向头结点还是首元结点,没有一个清晰的判断。今后应当注意这个知识点的理解与掌握。

2、在保存断开链中第一个结点的位置时,没有注意指针的连动性,导致没有保存成功。今后临时保存指针时,应当特别注意这一点。

代码实现

#include<iostream>
using namespace std;
typedef int ElemType;
typedef struct LNode{
    ElemType data;//结点的数据域
    struct LNode *next;//结点的指针域
}LNode,*LinkList;
int main(){
    int N,K,a1,a2,a3,i;
    LinkList q1,q11,q2,q3,L,p;
    L=new LNode;//创建一个带头结点的单链表
    L->next=NULL;
    cin>>N>>K;
    for(int i=N;i>0;i--){//编号存储在每个结点的数据域里
        p=new LNode;
        p->data=i;
        p->next=L->next;//前插法
        L->next=p;
    }
    while(K--){
        cin>>a1>>a2>>a3;
        p=L;//初始化,p指向头结点
        i=1;
        if(a3==0)//插入到最高层时,特殊处理
            q3=L;
        while(i!=N&&p){//遍历链表
            p=p->next;
            if(i==(a1-1))
            {
                q1=p;//保存断开链中第一个结点的前一个结点的位置
                q11=q1->next;//保存断开链中第一个结点的位置
            }
            else if(i==a2)
                q2=p;//保存断开链中最后一个结点的位置
            else if(i==a3)
                q3=p;//保存将要插入结点处的位置
            i++;
        }
        q1->next=q2->next;//把断开的链连接起来
        q2->next=q3->next;
        q3->next=q11;
    }
    p=L->next;//p指向首元结点
    i=10;
    while(i--&&p){
        cout<<p->data<<endl;//输出前10个的编号
        p=p->next;
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/DEAR_CXN/article/details/86566871