题目描述:
AI识别到面板上有N(1 ≤ N ≤ 100)个指示灯,灯大小一样,任意两个之间无重叠。
由于AI识别误差,每次别到的指示灯位置可能有差异,以4个坐标值描述AI识别的指示灯的大小和位置(左上角x1,y1,右下角x2,y2),
请输出先行后列排序的指示灯的编号,排序规则:
1、每次在尚未排序的灯中挑选最高的灯作为的基准灯,
2、找出和基准灯属于同一行所有的灯进行排序。两个灯高低偏差不超过灯半径算同一行(即两个灯坐标的差 ≤ 灯高度的一半)。
输入描述:
第一行为N,表示灯的个数
接下来N行,每行为1个灯的坐标信息,格式为:
编号 x1 y1 2 y2
*编号全局唯一
*1 ≤ 编号 ≤ 100
*0 ≤ x1 < x2 ≤ 1000
*0 ≤ y1 < y2 ≤ 1000
输出描述:
排序后的编号列表,编号之间以空格分隔
测试用例:
输入:
5
1 0 0 2 2
2 3 0 5 3
3 6 0 8 2
4 0 6 2 7
5 4 6 6 7
输出:
1 2 3 4 5
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int cmp(const void *a,const void *b){
int *arr1 = *(int **)a;
int *arr2 = *(int **)b;
int wa = arr1[2];
int wb = arr2[2];
return wa - wb;
}
int compare(const void *a,const void *b){
return *(int *)a - *(int *)b;
}
int main(){
int i,j,num;
scanf("%d",&num);
// int arr[num][5];
int **arr = (int **)malloc(sizeof(int*)*num);
for(i = 0;i < num;i++){
arr[i] = (int *)malloc(sizeof(int)*5);
for(j = 0;j < 5;j++){
scanf("%d",&arr[i][j]);
}
}
//按照y1对数组排序
qsort(arr,num,sizeof(int*),cmp);
//判断是否属于基准灯同一行,若属于同一行设置为1,下次不再排序
int flag[num];
memset(flag,0x00,sizeof(int)*num);
//收集结果
int res_arr[num],res_arr_cnt = 0;
//灯大小一样,取第一个灯计算半径
int radius = (arr[0][3] - arr[0][1])/2;
// printf("radius:%d",radius);
for(i = 0;i < num - 1;i++){
if(flag[i] != 0){
continue;
}
//判断基准灯与略低于基准灯是否同一行
if(arr[i + 1][2] - arr[i][2] <= radius){
//属于同一行
if(arr[i][1] <= arr[i + 1][1]){
res_arr[res_arr_cnt++] = arr[i][0];
res_arr[res_arr_cnt++] = arr[i + 1][0];
}else{
res_arr[res_arr_cnt++] = arr[i + 1][0];
res_arr[res_arr_cnt++] = arr[i][0];
}
flag[i] = 1;
flag[i + 1] = 1;
}else{
//不属于同一行
res_arr[res_arr_cnt++] = arr[i][0];
flag[i] = 1;
}
}
//对输出列表排序
qsort(res_arr,res_arr_cnt,sizeof(int),compare);
//释放内存
for(i = 0;i < num;i++){
printf("%d ",res_arr[i]);
free(arr[i]);
}
free(arr);
}