题解 | #牛牛的数组匹配#
牛牛的数组匹配
https://www.nowcoder.com/practice/3d3406f4a7eb4346b025cc592be5b875
/*分析: 首先关于连续子数组的长度无非包括1到b数组长度最大值;这是一个循环; 其次我们可以写一个求数组某段区间内的求和函数;方便求a数组的总和,也方便求b数组任意子数组的总和; 每次对某数组的某一段求和,然后动态滑动到数组b的最后;为一次循环; 其中每次循环需要与a数组的和做差,留下最接近的记住这段数组的下标; 全部循环结束后,根据循环中记录的最接近a数组的下标再导出该数组; */ # include<stdio.h> # include<math.h> /*定义结构体、该结构体存放b子数组的起点下标、子数组长度、和该子数组总和和a数组的差值; 建立一一对应的关系方便找到最接近的子数组;*/ typedef struct { int index; int length; int diff; }AM; AM Array_Match; //结构体跟新函数; void upgrade(int index, int length, int diff,AM *A_M) { A_M->index = index; A_M->length= length; A_M->diff = diff; } //求数组某段区间的和; int all_a(int l,int r,int Range_sum[]) { int i = 0,sum = 0; for(i = l; i <= r; i++) { sum+=Range_sum[i]; } return sum; } int main() { int n = 0, m = 0; int i = 0, j = 0; int a[10],b[10]; int A = 0, B = 0; scanf("%d %d",&n,&m);//输入a,b数组的长度 for(i = 0; i<n; i++)//给数组a赋值 { scanf("%d",&a[i]); } for(i = 0; i<m; i++)//给数组b赋值 { scanf("%d",&b[i]); } A = all_a(0,n-1,a);//对a数组求和,长度为0到n-1,a数组的整个长度; Array_Match.diff = A-b[0];//a数组总和和b子数组的差【赋个初值方便后续比较、更新】 //子数组滑动求和 for(i = 1; i <= m; i++)//子数组长度; { for(j = 0; j + i <= m; j++)//对于给定i长度的子数组,子数组能在整个b数组循环几次?答案就是j = m-i; { B = all_a(j,j+i-1,b);//每次对b的子数组求和,求和起点就是j,求和的终点是起点加子数组长度-1,对象是b数组; /*我们要比较a数组总和和b子数组的差,如果差小于最开始的初值,就更新diff. 以及跟新当前差值所对应的j和i,这样也就把最接近的子数组的下标记下来了*/ if(abs(A-B) < Array_Match.diff) { upgrade(j, i, abs(A-B), &Array_Match);//这样差值最小的j和i就找到了; } } } for(i=Array_Match.index; i<Array_Match.length+Array_Match.index; i++)//差值最小的j和i就找到后打印子数组b; { printf("%d ", b[i]); } return 0; }