题解 | 合并表记录
合并表记录
https://www.nowcoder.com/practice/de044e89123f4a7482bd2b214a685201
#include <stdio.h>
typedef struct{
int i;
int v;
}record;
int main() {
int n,i,j;
scanf("%d",&n);
record a[n];
for(i=0;i<n;i++){
scanf("%d %d",&a[i].i,&a[i].v);
}
for(i=0;i<n;i++){
for(j=i+1;j<n;j++){
if(a[i].i==a[j].i){
a[i].v+=a[j].v;
a[j].v=0;
a[j].i=-1;
}
if(a[i].i>a[j].i){
record t=a[i];
a[i]=a[j];
a[j]=t;
}
}
}
for(i=0;i<n;i++){
if(a[i].i>=0){
printf("%d %d\n",a[i].i,a[i].v);
}
}
return 0;
}
刚开始我用的是数组,大小固定为1000(10000也试了),但题目给的索引范围最大可达 11,111,111,远超1000。所以当输入的 index 大于等于1000时,a[index] 就会数组越界,从而引发段错误(Segmentation Fault)。
你的测试通过率是 11/12,说明绝大部分用例的索引都在 0~999 之间,但最后一个用例中出现了较大的索引(不出意外,11111111),导致程序崩溃。
解题思路
- 数据结构定义 record 结构体,包含索引 i 和数值 v,用于存储每条原始记录。
- 合并相同索引外层循环 i 固定当前记录,内层循环 j 扫描后续记录:如果 a[i].i == a[j].i,则将 a[j].v 累加到 a[i].v,然后清除 a[j](设置 a[j].i = -1,a[j].v = 0),相当于将重复记录合并到 a[i] 中。
- 排序在同一个内层循环中,紧接着判断:如果 a[i].i > a[j].i,则交换两条记录。这样,每遍历一次内层循环,都会把较小的索引换到 a[i] 位置,相当于选择排序(或冒泡排序的变种)。多次循环后,所有有效记录会按照索引升序排列,而无效记录(i = -1)会被交换到数组前部。
- 输出遍历数组,仅输出 a[i].i >= 0 的记录(即未被清除的合并结果),此时顺序已经是升序。