首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

【华为OD-E卷-03 ai面板识别 100分(python、java、c++、js、c)】

  • 25-03-07 19:02
  • 3230
  • 9317
blog.csdn.net

【华为OD-E卷-ai面板识别 100分(python、java、c++、js、c)】

题目

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

用例

用例一:
输入:
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
  • 6
输出:
1 2 3 4 5
  • 1

python解法

  • 解题思路:
  • 这道题目涉及的是按行排列一组灯光,每个灯光的位置和半径给定,目标是将这些灯光按照一定规则排序后输出其编号。

输入与数据结构:

输入的每一行包含五个数:灯光的编号(id)、灯光的左上角坐标(cx、cy)、右下角坐标(r)和宽度。通过这些数据可以确定每个灯光的圆心坐标、半径以及该灯光的 id。
目标:

我们需要先按灯光的 cy(圆心的纵坐标)进行排序,这样可以将所有在同一行的灯光分组。
对于每一行的灯光,需要根据 cx(圆心的横坐标)进行排序。最终输出的结果是按行排序后,每行灯光按 cx 排序后的 id 组成的序列。
步骤:

首先,先将输入的灯光数据转换成 Light 对象,每个对象包含其编号、圆心坐标和半径。
然后,按照纵坐标 cy 对灯光进行排序,将相同纵坐标(同一行)的灯光分到一起。
对于每行的灯光,按横坐标 cx 排序,并输出其 id。

class Light:
    # 灯光类,初始化时需要提供灯光的id、圆心坐标 (cx, cy) 和半径 r
    def __init__(self, id, cx, cy, r):
        self.id = id  # 灯光的编号
        self.cx = cx  # 圆心横坐标
        self.cy = cy  # 圆心纵坐标
        self.r = r    # 半径

# 输入n代表灯光数量
n = int(input())
# 输入灯光数据:每个灯光包含 [id, left, top, right, bottom] 信息
arr = [list(map(int, input().split())) for _ in range(n)]

# 将输入的灯光数据转换成 Light 对象,计算圆心和半径
lights = [Light(ele[0], (ele[1] + ele[3]) // 2, (ele[2] + ele[4]) // 2, (ele[3] - ele[1]) // 2) for ele in arr]

def sort_lights():
    # 按照纵坐标 (cy) 排序,这样可以将同一行的灯光放在一起
    lights.sort(key=lambda l: l.cy)
    
    res = []  # 存储最终排序后的灯光id
    same_row = []  # 临时存储同一行的灯光
    base = lights[0]  # 设置基准灯光为第一个灯光
    same_row.append(base)  # 将基准灯光加入到同一行灯光中

    # 遍历灯光列表,从第二个灯光开始
    for i in range(1, len(lights)):
        cur = lights[i]  # 当前灯光
        # 如果当前灯光的纵坐标 (cy) 和基准灯光的纵坐标之差小于等于基准灯光的半径,则认为它们在同一行
        if cur.cy - base.cy <= base.r:
            same_row.append(cur)  # 当前灯光加入到同一行
        else:
            # 如果当前灯光不在同一行,首先按横坐标 (cx) 对这一行的灯光进行排序
            same_row.sort(key=lambda l: l.cx)
            # 将这一行的灯光id加入结果
            res.extend([l.id for l in same_row])
            same_row.clear()  # 清空当前行的灯光
            base = cur  # 更新基准灯光
            same_row.append(base)  # 将当前灯光加入新的行

    # 如果最后还有一行灯光没有加入结果,按横坐标 (cx) 排序后加入
    if same_row:
        same_row.sort(key=lambda l: l.cx)
        res.extend([l.id for l in same_row])

    # 返回结果,灯光的id按照每行的顺序排列
    return " ".join(map(str, res))

# 输出排序后的灯光编号
print(sort_lights())

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51

java解法

  • 解题思路
  • 这道题目要求我们根据灯光的坐标和半径对灯光进行排序,并输出灯光的编号。具体步骤如下:

输入数据:

输入首先包含一个整数 n,表示灯光的数量。
接下来,输入 n 行,每行包含五个整数:灯光的 id、左上角坐标 (x1, y1)、右下角坐标 (x2, y2)。
目标:

每个灯光的实际位置是其圆心,圆心坐标可以通过 (x1 + x2) / 2 和 (y1 + y2) / 2 计算得到,半径可以通过 (x2 - x1) / 2 计算得到。
将灯光按照纵坐标 y 排序,确保在同一行的灯光按横坐标 x 排序后输出。
处理同一行的灯光,将相同纵坐标的灯光分到一组,然后按横坐标排序后输出每一行灯光的 id。
步骤:

先创建一个 Indicator 类来存储每个灯光的信息,包括 id、圆心的坐标 (x, y) 和半径 radius。
然后将灯光按纵坐标 y 排序,接着根据 radius 来判断哪些灯光属于同一行。
对于每一行的灯光,根据横坐标 x 进行排序,最后按顺序输出灯光的 id。

import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        
        // 输入灯光数量n
        int n = input.nextInt();
        // 创建灯光数组
        Indicator[] indicators = new Indicator[n];

        // 输入每个灯光的数据:id, x1, y1, x2, y2
        for (int i = 0; i < n; i++) {
            int id = input.nextInt();
            int x1 = input.nextInt();
            int y1 = input.nextInt();
            int x2 = input.nextInt();
            int y2 = input.nextInt();
            
            // 创建Indicator对象,并计算灯光的圆心坐标 (x, y) 和半径 radius
            indicators[i] = new Indicator(id, (x1 + x2) / 2, (y1 + y2) / 2, (x2 - x1) / 2);
        }

        // 调用sortIndicators方法返回排序后的灯光编号,并输出
        System.out.println(sortIndicators(indicators));
    }

    // 排序灯光的核心方法
    public static String sortIndicators(Indicator[] indicators) {
        // 按照灯光的纵坐标 y 排序
        Arrays.sort(indicators, Comparator.comparingInt(ind -> ind.y));
        
        // 用于存储同一行的灯光
        List<Indicator> rowGroup = new ArrayList<>();
        StringBuilder sortedIds = new StringBuilder();
        
        // 设置当前行的基准灯光
        Indicator current = indicators[0];
        rowGroup.add(current);  // 将基准灯光加入行组

        // 遍历灯光数组,处理每个灯光
        for (int i = 1; i < indicators.length; i++) {
            Indicator next = indicators[i];
            // 如果当前灯光与基准灯光的纵坐标差不超过半径,说明它们在同一行
            if (next.y - current.y <= current.radius) {
                rowGroup.add(next);  // 加入同一行
            } else {
                // 当前行的灯光已处理完,按横坐标 x 排序
                rowGroup.sort(Comparator.comparingInt(ind -> ind.x));
                // 将这一行的灯光编号添加到结果中
                for (Indicator ind : rowGroup) {
                    sortedIds.append(ind.id).append(" ");
                }
                rowGroup.clear();  // 清空当前行的灯光
                current = next;  // 更新基准灯光为当前灯光
                rowGroup.add(current);  // 将当前灯光加入新的一行
            }
        }

        // 如果最后还有灯光未处理,按横坐标 x 排序后加入
        if (!rowGroup.isEmpty()) {
            rowGroup.sort(Comparator.comparingInt(ind -> ind.x));
            for (Indicator ind : rowGroup) {
                sortedIds.append(ind.id).append(" ");
            }
        }

        // 返回结果,并去除末尾多余的空格
        return sortedIds.toString().trim();
    }
}

// Indicator 类表示每个灯光的属性
class Indicator {
    int id;     // 灯光的编号
    int x;      // 圆心的横坐标
    int y;      // 圆心的纵坐标
    int radius; // 半径

    // 构造函数,初始化灯光的id、x、y和半径
    public Indicator(int id, int x, int y, int radius) {
        this.id = id;
        this.x = x;
        this.y = y;
        this.radius = radius;
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89

C++解法

  • 解题思路
更新中
  • 1

C解法

  • 解题思路

  • 题目要求我们根据给定的一组灯光信息(每个灯光的编号、左上角和右下角坐标),将灯光按照一定规则进行排序并输出。具体步骤如下:

输入数据结构:

输入一个整数 n 表示灯光的数量。
对于每个灯光,输入五个整数:灯光的编号 id,左上角坐标 (x1, y1) 和右下角坐标 (x2, y2)。
目标:

每个灯光的实际位置是其圆心,圆心坐标可以通过 (x1 + x2) / 2 和 (y1 + y2) / 2 计算得到,半径可以通过 (x2 - x1) / 2 计算得到。
将灯光按纵坐标 y 排序,确保在同一行的灯光按横坐标 x 排序后输出。
处理同一行灯光:

根据纵坐标的差值判断灯光是否属于同一行:如果当前灯光与上一行灯光的纵坐标差不超过基准灯光的半径(y 坐标差小于等于半径),则认为它们在同一行。
对于每一行灯光,按横坐标 x 排序,并按顺序输出灯光的 id。
步骤:

使用结构体 Light 来存储每个灯光的编号、圆心坐标和半径。
通过 qsort 按照纵坐标对灯光进行排序,然后根据基准灯光的 y 坐标差值来分组处理。
对每一组同一行的灯光按横坐标 x 排序,最后输出每行灯光的 id。

#include 
#include 

// 定义灯光结构体,包含id, 圆心坐标 (x, y) 和半径 r
typedef struct {
    int id;
    int x;
    int y;
    int r;
} Light;

// 比较函数,用于按照纵坐标 y 排序灯光
int compareY(const void* a, const void* b) {
    Light* lightA = (Light*)a;
    Light* lightB = (Light*)b;
    return lightA->y - lightB->y; // 纵坐标较小的排前面
}

// 比较函数,用于按照横坐标 x 排序灯光
int compareX(const void* a, const void* b) {
    Light* lightA = (Light*)a;
    Light* lightB = (Light*)b;
    return lightA->x - lightB->x; // 横坐标较小的排前面
}

// 确定灯光的输出顺序
void determineOrder(Light lights[], int n) {
    // 按照纵坐标 y 排序灯光
    qsort(lights, n, sizeof(Light), compareY);
    
    Light sameRow[n];  // 存储当前行的灯光
    int sameRowCount = 0;  // 当前行的灯光数量
    Light reference = lights[0];  // 设置基准灯光
    sameRow[sameRowCount++] = reference;  // 将基准灯光加入当前行

    // 遍历灯光数组,判断同一行的灯光
    for (int i = 1; i < n; i++) {
        Light current = lights[i];
        // 判断当前灯光是否与基准灯光在同一行:y差值小于等于基准灯光的半径
        if (current.y - reference.y <= reference.r) {
            sameRow[sameRowCount++] = current;  // 加入当前行
        }
        else {
            // 如果当前灯光不在同一行,先对当前行的灯光按横坐标 x 排序
            qsort(sameRow, sameRowCount, sizeof(Light), compareX);
            // 输出当前行的所有灯光编号
            for (int j = 0; j < sameRowCount; j++) {
                printf("%d ", sameRow[j].id);
            }
            sameRowCount = 0;  // 清空当前行
            reference = current;  // 更新基准灯光为当前灯光
            sameRow[sameRowCount++] = reference;  // 将当前灯光加入新的行
        }
    }

    // 输出最后一行的灯光编号
    if (sameRowCount > 0) {
        qsort(sameRow, sameRowCount, sizeof(Light), compareX);
        for (int j = 0; j < sameRowCount; j++) {
            printf("%d ", sameRow[j].id);
        }
    }

    // 输出换行符
    printf("\n");
}

// 主函数
int main() {
    int n;
    scanf("%d", &n);  // 输入灯光的数量
    Light lights[n];  // 声明灯光数组

    // 输入每个灯光的信息:id, 左上角坐标 (x1, y1), 右下角坐标 (x2, y2)
    for (int i = 0; i < n; i++) {
        int id, x1, y1, x2, y2;
        scanf("%d %d %d %d %d", &id, &x1, &y1, &x2, &y2);
        lights[i].id = id;
        lights[i].x = (x1 + x2) / 2;  // 计算灯光的圆心横坐标
        lights[i].y = (y1 + y2) / 2;  // 计算灯光的圆心纵坐标
        lights[i].r = (x2 - x1) / 2;  // 计算灯光的半径
    }

    // 调用determineOrder函数对灯光进行排序并输出结果
    determineOrder(lights, n);

    return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89

JS解法

  • 解题思路

  • 本题的核心是根据每个灯光的信息(圆形区域的左上角和右下角坐标),计算每个灯光的圆心位置和半径,并按照一定的规则排序这些灯光。具体要求是:

首先按照纵坐标(y)对灯光进行排序,确保同一水平线上的灯光按顺序排列。
同一行的灯光按横坐标(x)排序。
需要判断哪些灯光位于同一行,判断规则是两个灯光的纵坐标差是否在基准灯光的半径范围内(即:nextLight.midY - currentLight.midY <= currentLight.rad)。
处理步骤:
输入解析:通过 readline 持续读取输入,直到读取到所有的灯光数据。
数据转换:解析每个灯光的坐标信息,计算每个灯光的圆心坐标(midX, midY)和半径(rad)。
排序逻辑:
纵坐标排序:按 midY 排序,确保灯光按照从上到下的顺序排列。
同一行的灯光判断:判断灯光是否在同一行,如果在同一行,则将它们按横坐标 midX 排序,输出灯光的 id。
输出结果:每次处理完一行灯光后,输出该行灯光的 id,最后输出所有灯光的排序结果。

// 使用 readline 创建接口以便读取输入
const readline = require("readline");

const rl = readline.createInterface({
    input: process.stdin,
    output: process.stdout,
});

// 用来存储输入的数据
let data = [];
let numberOfLights;

// 每次读取一行数据
rl.on("line", (line) => {
    data.push(line); // 将每行数据存入数组

    // 第一行是灯光的数量
    if (data.length === 1) {
        numberOfLights = parseInt(data[0]);  // 读取灯光数量
    }

    // 当读取到足够的灯光数据时,开始处理
    if (numberOfLights && data.length === numberOfLights + 1) {
        data.shift(); // 去掉第一个元素,即灯光的数量

        // 将每行灯光数据解析为对象,存储灯光的id和计算出的圆心坐标、半径
        const lights = data.map((str) => {
            const [id, x1, y1, x2, y2] = str.split(" ").map(Number);
            return { 
                id, 
                midX: (x1 + x2) / 2, // 计算圆心的横坐标
                midY: (y1 + y2) / 2, // 计算圆心的纵坐标
                rad: (x2 - x1) / 2 // 计算圆的半径
            };
        });

        // 调用函数来计算并打印结果
        console.log(computeOrder(lights));

        // 清空数据准备下一轮的输入
        data = [];
    }
});

// 计算灯光的排序顺序
function computeOrder(lightArray) {
    // 先按纵坐标 midY 排序
    lightArray.sort((lightA, lightB) => lightA.midY - lightB.midY);

    const finalOrder = []; // 存储最终的排序结果
    let rowLights = []; // 存储当前行的灯光
    let currentLight = lightArray[0]; // 当前行的基准灯光
    rowLights.push(currentLight); // 将基准灯光加入当前行

    // 遍历灯光数组,分行处理灯光
    for (let i = 1; i < lightArray.length; i++) {
        const nextLight = lightArray[i];

        // 如果当前灯光与基准灯光的纵坐标差在半径范围内,认为它们在同一行
        if (nextLight.midY - currentLight.midY <= currentLight.rad) {
            rowLights.push(nextLight); // 加入当前行
        } else {
            // 当前行已结束,处理并输出该行的灯光
            finalizeRow(rowLights, finalOrder);
            rowLights = [nextLight]; // 当前灯光开始新的行
            currentLight = nextLight; // 更新基准灯光为当前灯光
        }
    }

    // 处理最后一行的灯光
    if (rowLights.length > 0) {
        finalizeRow(rowLights, finalOrder);
    }

    // 返回最终排序后的灯光编号(id)
    return finalOrder.join(" ");
}

// 将当前行的灯光按横坐标 midX 排序,并将 id 输出
function finalizeRow(row, result) {
    row.sort((a, b) => a.midX - b.midX).forEach((light) => result.push(light.id)); // 按横坐标排序,并收集 id
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

注:本文转载自blog.csdn.net的CodeClimb的文章"https://blog.csdn.net/CodeClimb/article/details/144511138"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top