蓝桥杯---自行车停放

  • 题目: 

资源限制

内存限制:256.0MB   Java时间限制:3.0s 

问题描述

  有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

  • 思路1:直接用Java中的linkedlist(超时)

    • 定义一个链表park,然后将每一辆车的编号的存放进去。

    • 在存放时,判断参照的车辆y所在链表的位置然后用linkedlist的indexOf(y)找到y所在链表的位置。

    • 对于z=0(停放在左边)则用add(indexOf(y),x)插入在y的位置。

    • 对于z=1(停放在右边)则用add(indexOf(y)+1,x)插入在其y右边的位置。

  • 问题:

    • 复杂度太大了,到最后一个样例的时候超时了。(indexof是要花时间找的,然后遍历n各大小的数组也是要时间的)
  • 代码:

package BlueBridge;

/**
 * @author S'L
 * @date 2023/2/1 9:02
 *
 * 题目:自行车停放   有n辆自行车依次来到停车棚,除了第一辆自行车外,每辆自行车都会恰好停放在已经在停车棚里的某辆自行车的左边或右边。
 *                  给定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
 */

import java.util.LinkedList;
import java.util.Scanner;

public class BicycleParking {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        int[][] orders = new int[n - 1][3];
        for (int i = 0; i < orders.length; i++)
            for (int j = 0; j < orders[i].length; j++)
                orders[i][j] = in.nextInt();
        firstMethod(n, m, orders);
        in.close();
    }


    public static void firstMethod(int n, int m, int[][] orders) { //用java提供的链表来做(超时)
        LinkedList<Integer> park = new LinkedList<>();
        park.add(m);
        for (int i = 0; i < orders.length; i++) {
            int index = park.indexOf(orders[i][1]);
            if (orders[i][2] == 0) {  //停y左边
                park.add(index, orders[i][0]);
            } else {  //停y右边
                park.add(index + 1, orders[i][0]);
            }
        }
        for (int i = 0; i < park.size(); i++) {
            System.out.print(park.get(i) + " ");
        }
    }
}

 

  •  思路2:自定义双链表

    • 看了一下其他博主的思路,要做到不超时,用过空间换时间的方式,定义一个数组来存储每一个自行车,存储的位置(下标)就是自行车的编号,做到随机查找,将搜索y号车的时间给省掉。
    • 定义一个双向节点(类),其属性为为data(自行车编号),next(下一辆自行车),prior(前一辆自行车)。
    • 定义一个存放双向节点的数组,设置其大小为100001(因为是存储其编号且编号无序,所以只能将数组的空间最大化设置)。
    • 对每一辆自行车先将其定义为一个双向节点,然后将其存入数组中,其数组下标为其自行车编号。
    • 对于z=0(停放在左边)则先将x的前驱(prior),后继(next)设为y.prior和y;然后判断y是否有前驱(y.prior!=null),如果有则为y的前驱设置其后继为x;最后改变y的前驱。

    • 特别的,停左边时还要多判断一步,就是参照的这辆车y是否为第一辆车,如果是则要改变第一辆车为新停的车辆x。

    • 对于z=1(停放在右边)则先将x的前驱(prior),后继(next)设为y和y.next;然后判断y是否有后继(y.next!=null),如果有则为y的后继设置其前驱为x;最后改变y的后继。

  • 代码:

package BlueBridge;

/**
 * @author S'L
 * @date 2023/2/1 9:02
 *
 * 题目:自行车停放   有n辆自行车依次来到停车棚,除了第一辆自行车外,每辆自行车都会恰好停放在已经在停车棚里的某辆自行车的左边或右边。
 *                  给定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
 */

import java.util.LinkedList;
import java.util.Scanner;

public class BicycleParking {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        int[][] orders = new int[n - 1][3];
        for (int i = 0; i < orders.length; i++)
            for (int j = 0; j < orders[i].length; j++)
                orders[i][j] = in.nextInt();
//        firstMethod(n, m, orders);
        secondMethod(n,m,orders);
        in.close();
    }

    private static void secondMethod(int n, int m, int[][] orders) {  //用自定义链表做
            doubleList[] bikeArray = new doubleList[100001];  //用一个数组记录每一辆自行车为止,其存储位置即自行车编号(方便随机查找)
        doubleList firstBike = new doubleList();  //第一辆自行车
        firstBike.data = m;
        firstBike.next = null;
        firstBike.prior = null;
        bikeArray[firstBike.data] = firstBike;
        for (int i = 0; i < orders.length; i++) {
                doubleList bike = new doubleList();
                bike.data = orders[i][0];  //存储新的一辆自行车
                bikeArray[bike.data] = bike;
                if (orders[i][2]==0){  //停在左边
                    bike.next = bikeArray[orders[i][1]];
                    bike.prior = bikeArray[orders[i][1]].prior;
                    if (bikeArray[orders[i][1]].prior!=null){
                        bike.prior.next = bike;
                    }
                    bikeArray[orders[i][1]].prior = bike;
                    if(bikeArray[orders[i][1]].data==firstBike.data)  //如果参照的车正好为原来的第一辆车
                        firstBike = bike;  //则将第一辆车定为新停放在其左边的车
                }else {  //停在右边
                    bike.next = bikeArray[orders[i][1]].next;
                    bike.prior = bikeArray[orders[i][1]];
                    if (bikeArray[orders[i][1]].next!=null){
                        bikeArray[orders[i][1]].next.prior = bike;
                    }
                    bikeArray[orders[i][1]].next = bike;
                }

        }
        doubleList cursor = firstBike;  //定位第一辆车
        while(cursor!=null){  //遍历
            System.out.print(cursor.data+" ");
            cursor = cursor.next;
        }
    }
}

class doubleList{
    int data;
    doubleList next,prior;
    public doubleList(){
    }
}

(两段代码本来是一起的被分开了,如果中途有点错,见谅😁,有错误欢迎指正哈,如果有不小心侵权的联系删除哈)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值