蓝桥杯 算法训练 自行车停放(Java)

问题描述:

有n辆自行车依次来到停车棚,除了第一辆自行车外,每辆自行车都会恰好停放在已经在停车棚里的某辆自行车的左边或右边。(e.g.停车棚里已经有3辆自行车,从左到右编号为:3,5,1。现在编号为2的第4辆自行车要停在5号自行车的左边,所以现在停车棚里的自行车编号是:3,2,5,1)。给定n辆自行车的停放情况,按顺序输出最后停车棚里的自行车编号。

输入格式:

  第一行一个整数n。
  第二行一个整数x。表示第一辆自行车的编号。
  以下n-1行,每行3个整数x,y,z。
  z=0时,表示编号为x的自行车恰停放在编号为y的自行车的左边
  z=1时,表示编号为x的自行车恰停放在编号为y的自行车的右边

输出格式:

从左到右输出停车棚里的自行车编号

样例输入:

4
3
1 3 1
2 1 0
5 2 1

样例输出:

3 2 5 1

数据规模和约定:

n<=100000
自行车编号为不超过100000的正整数。

思路:

  1. 由题意我们可以知道,根据每一行的最后一列的值的不同,自行车的号码就放置在该倒数第二列的车号码的左边或者是右边。因此需要双向链表的算法来进行解题!还有就是题目中说的第一辆自行车并不是说这车一定位于第一位,本人一开始理解有偏差,误认为第一辆车的位置不能发生改变!!!

  1. 首先让我们来回顾一下双向链表的知识点。我们知道在单链表中的某个结点中有且只有一个顺时针方向寻找的后一个结点,而如果想要寻找该结点的直接前驱,那么只能从头节点一直遍历到该节点的前一个结点。顾名思义,双向链表则是在该结点中添加一个直接前驱即可。

  1. 那么由上述总结我们便可以清楚该节点的结构特点:(前驱指针域:prior、数据域:data、后继指针域:next )而说到java,我们这个可以把这个结点变成一个类,如:

class doubleLinkedList{
    int data;
    doubleLinkedList prior,next;
    public doubleLinkedList(){

    }
}

属性:int类型,doubleLinkedList类类型。(作用于指向下一个或者前一个的类)可以实现c中的指针的功能。

  1. 前期准备工作

Scanner scan = new Scanner(System.in);
        int num1,num2,charge;
        int count, firstNum;
        doubleLinkedList x, y;

        count = scan.nextInt();
        firstNum = scan.nextInt();

        doubleLinkedList firstList = new doubleLinkedList();
        firstList.data = firstNum;
        firstList.prior = null;
        firstList.next = null;

        doubleLinkedList[] list = new doubleLinkedList[100010];
        list[firstNum] = firstList;

① num1:存储每行的第一个数 、 num2:存储每行的第二个数、charge:存储前两数的位置

count:单车号牌的个数、 firstNum:第一个单车号牌的数字

② 建立头结点,把数值赋值给属性data,并且先把前后指针先设置为空

③ 建立该类类型的数组,注意:数组的长度应该大于100000,否则测试的时候会出现运行错误的情况!

④ 将头节点的对象放置在该数组的对应的坐标位置。

         x = new doubleLinkedList();
            x.data = num1;
            list[num1] = x;

图例说明:

完整代码:



import java.util.Scanner;

/**
 * @author Qik~
 * @create 2023-01-21 9:01
 */
public class Main {
    public static void main(String[] args) {

        Scanner scan = new Scanner(System.in);
        int num1,num2,charge;
        int count, firstNum;
        doubleLinkedList x, y;

        count = scan.nextInt();
        firstNum = scan.nextInt();

        doubleLinkedList firstList = new doubleLinkedList();
        firstList.data = firstNum;
        firstList.prior = null;
        firstList.next = null;

        doubleLinkedList[] list = new doubleLinkedList[1000100];

        list[firstNum] = firstList;

        for (int i = 1; i < count; i++) {
            num1 = scan.nextInt();
            num2 = scan.nextInt();
            charge = scan.nextInt();

            x = new doubleLinkedList();
            x.data = num1;
            list[num1] = x;

            y = list[num2];
            if (charge == 0) {
                x.next = y;
                if (y.prior != null) {
                    x.prior = y.prior;
                    y.prior.next = x;
                } else {
                    x.prior = null;
                }
                y.prior = x;
                if (y == firstList) {
                    firstList = x;
                }
            }


            if (charge == 1) {
                x.prior = y;
                if (y.next != null) {
                    x.next = y.next;
                    y.next.prior = x;
                } else {
                    x.next = null;
                }
                y.next = x;
            }
        }

        while (firstList != null) {
            System.out.print(firstList.data + " ");
            firstList = firstList.next;

        }


    }
}

class doubleLinkedList{
    int data;
    doubleLinkedList prior,next;
    public doubleLinkedList(){

    }

}


测试结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Luca-s-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值