自行车停放c语言,蓝桥杯算法训练 自行车停放(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的正整数。

算法思路

由题意可知该算法要根据给定的自行车停放顺序来得出最后的自行车排列顺序。由于给定了首位自行车的编号,所以我们可以设定一个字符串,字符串最初值为“a首位自行车的编号b”(这里在编号的两边加上“a”和“b”是作为每个编号的边界,这样可防止一些不可预测的巧合而导致的错误)然后遍历取出每组新加进来的自行车位置信息,通过字符串的indexof来返回要找的自行车的位置,接着将新的自行车编号在指定位置insert即可。

算法实现

我的未完全正确的算法(正确率80%)

import java.util.Scanner;

public class Main{

public static void main(String[] args) {

Scanner input = new Scanner(System.in);

int n = input.nextInt();//自行车的数量

String index = input.next();//第一辆自行车的编号

String[][] arr = new String[n-1][3];

for (int i = 0; i < n-1; i++) {

for (int j = 0; j < 3; j++) {

arr[i][j] = input.next();

}

}

StringBuffer s = new StringBuffer("a" + index + "b");//用于保存最终自行车停放位置序列,两边加“a”“b”的目的是为编号的两边加上一个界符,防止因为字符串粘结时出现相同的编号

for (int i = 0; i < n-1; i++) {

int flag = Integer.parseInt(arr[i][2]);//左右标记位

String oldcar = "a" + arr[i][1] + "b";//原来的车

String newcar = "a" + arr[i][0] + "b";//新加入的车

if(flag == 0){//从左边插入

s.insert(s.indexOf(oldcar),newcar);

}

if(flag == 1){//从右边插入

s.insert(s.indexOf(oldcar)+oldcar.length(),newcar);

}

}

String temp = s.toString().replace("b"," ");//将每个编号的右边界“b”替换为空格

System.out.println(temp.replace("a",""));//将编号的左边界“a”消去

}

}

注意:这个程序提交测试时正确率只有80%,当测试数据为100000个时会出现越界的错误,这个错误我百度了好多还是没有解决,希望有大佬在下方评论指正。

完全正确的算法如下

import java.util.ArrayList;

import java.util.Scanner;

public class Main{

public static class TreeNode{

int left;

int right;

}

public static void main(String[] args) {

Scanner sc = new Scanner(System.in);

int n = sc.nextInt();

TreeNode [] node = new TreeNode[100000+2];

int k = sc.nextInt();

for (int i = 0; i <= 100001; i++) {

node[i]=new TreeNode();

node[i].left = -1;

node[i].right = -1;

}

node[k].left = 0;

node[k].right = 100001;

node[0].right = k;

node[n + 1].left = k;

for (int i = 0; i

int x=sc.nextInt();

int y = sc.nextInt();

int z = sc.nextInt();

if (z == 0) {

node[x].left = node[y].left;

node[x].right = y;

node[node[y].left].right = x;

node[y].left = x;

} else {

node[x].right = node[y].right;

node[x].left = y;

node[node[y].right].left = x;

node[y].right = x;

}

}

int index=0;

for (;;) {

if(node[index].right==100001) break;

System.out.print (node[index].right+" ");

index=node[index].right;

}

}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值