题解 | #牛牛的数组匹配#

牛牛的数组匹配

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

全部评论

相关推荐

评论
1
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务