AI识别面板_100分_B卷_逻辑分析模拟

AI识别面板

题目描述:

AI识别到面板上有N (1 ≤N ≤ 100) 个指示灯,灯大小一样,任意两个之间无重叠。
由于AI识别误差,每次别到的指示灯位置可能有差异,以4个坐标值描述AI识别的指示灯的大小和位置(左上角x1,y1,右下角x2,y2)。
请输出先行后列排序的指示灯的编号,排序规则:
  1.每次在尚未排序的灯中挑选最高的灯作为的基准灯
  2.找出和基准灯属于同一行所有的灯进行排序。两个灯高低偏差不超过灯半径算同一行(即两个灯坐标的差灯高度的一半)。

输入输出描述:

输入描述:

  第一行为N,表示灯的个数
  接下来N行,每行为1个灯的坐标信息,格式为:
  编号x1 y1 x2 y2
  1:编号全局唯一
  2:1< 编号 ≤100
  3:0≤ x1 < x2 ≤1000
  4:0≤ y1 < y2 ≤ 1000

输出描述:

  排序后的编号列表,编号之间以空格分隔

示例1:

输入:
	5
	1 0 0 2 2
	2 6 1 8 3
	3 3 2 5 4
	5 5 4 7 6
	4 0 4 2 6
输出:
	1 2 3 4 5

解题思路:

以示例为例子,本题描述不是特别的清洗,可以坐标图,具体思路:
1、先按照给出的左上角、右下角坐标,求出灯泡的中心坐标、半径。
2、根据题目的排序描述和结果输出情况,可推测出“最高的灯泡”应该是指:纵左边值最小,如果纵坐标值相等,则应该是横坐标最小的那个。故可以根据步骤1中得到的中心坐标对灯泡数组进行排序,以便于每次找出最高的灯泡。
3、开始进行模拟,每轮找出最高的灯泡,然后找与之同行的灯泡,找完所有同行的灯泡之后;循环开始一下轮…直到所有灯泡遍历结束。
在这里插入图片描述

代码:

public static void main(String[] args) {
	Scanner scanner = new Scanner(System.in);
	int n = Integer.parseInt(scanner.nextLine());
	int[][] lanterns = new int[n][4];

	// 根据灯泡的左上角和右下角的左边,计算出其中心坐标和半径
	for (int i = 0; i < n; i++) {
		String[] split = scanner.nextLine().split(" ");
		lanterns[i][0] = Integer.parseInt(split[0]);
		// 中心坐标的 x
		lanterns[i][1] = (Integer.parseInt(split[1]) + Integer.parseInt(split[3])) / 2;
		// 中心坐标的 y
		lanterns[i][2] = (Integer.parseInt(split[2]) + Integer.parseInt(split[4])) / 2;
		// 半径 r
		lanterns[i][3] = (Integer.parseInt(split[3]) - Integer.parseInt(split[1])) / 2;
	}

	// 先按照,纵坐标排序(即题目中的高度,高度值越小代表越高),众坐标相等,则按照横坐标排序
	Arrays.sort(lanterns, (a, b)->a[2] != b[2] ? a[2] - b[2] : a[1] - b[1]);
	List<int[]> sameRowLanterns = new ArrayList<>();
	int[] base = lanterns[0];
	sameRowLanterns.add(base);

	StringBuilder sb = new StringBuilder();
	for (int i = 1; i < n; i++) {

		// 两个灯高低偏差不超过灯半径算同一行(即两个灯坐标的差灯高度的一半)
		if (lanterns[i][2] - base[2] <= base[3]) {
			sameRowLanterns.add(lanterns[i]);
		} else {
			// 从未排序的灯中挑选出最高的那颗
			base = lanterns[i];
			sameRowLanterns.add(base);
		}
	}

	// 输出结果
	if (!sameRowLanterns.isEmpty()) {
		for (int[] lantern : sameRowLanterns) {
			sb.append(lantern[0] + " ");
		}
	}

	System.out.println(sb.substring(0, sb.length() - 1).toString());
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值