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;
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

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
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

注意:

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

注:本文转载自blog.csdn.net的CodeClimb的文章"https://blog.csdn.net/CodeClimb/article/details/144511138"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!