BC156. 牛牛的数组匹配
描述
输入描述
输出描述
输出子数组之和最接近 a 的子数组示例1
输入:
2 6 30 39 15 29 42 1 44 1
输出:
29 42
示例2
输入:
6 1 50 47 24 19 46 47 2
输出:
2
C 解法, 执行用时: 2ms, 内存消耗: 292KB, 提交时间: 2022-03-13
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> int main() { int arr1[100] = { 0 }; int arr2[100] = { 0 }; int a, b; int x, y; scanf("%d%d", &a, &b); int sum1 = 0; int sum2 = 0; int i = 0; for (i = 0;i < a;i++) { scanf("%d", &arr1[i]); sum1 += arr1[i]; } for (i = 0;i < b;i++) { scanf("%d", &arr2[i]); sum2 += arr2[i]; } int min = 1000000; //这里少了一个遍历 for (i = 0;i < b - 1;i++) { int m = i; int summ = 0; int j = 0; for (j = i + 1;j < b;j++) { while (m <= j) { summ += arr2[m]; m++; } if (min > abs(summ - sum1)) { //找到了 min = abs(summ - sum1); x = i; y = j; } m = i; summ = 0; } } if (b == 1) { printf("%d", arr2[0]); } else { for (i = x;i <= y;i++) { printf("%d ", arr2[i]); } } return 0; }
C 解法, 执行用时: 2ms, 内存消耗: 296KB, 提交时间: 2022-06-16
#include <stdio.h> #include <math.h> int* compute(int arr2[], int m, int i, int sum1, int sum2){ int arr[2]; //存放两个参数 找到本轮最优解时候的sum 和 j int sub = 0; for(int n = 0; n < i; n++) sum2 -= arr2[n]; //本轮初始值 for(int j = m - 1; j >= i; j--){ if(abs(sum2 - arr2[j] - sum1) < abs(sum2 - sum1)) //比较差值 sum2 -= arr2[j]; else{ arr[0] = sum2; //当轮最优解元素和 arr[1] = j; //当轮最优解尾元素下标 break; } } return arr; } /*思路:从完整数组开始,不断去掉前面的一个元素,用剩下的子数组进行下轮比较; *每轮判断规则(如果满足减去数组2当前的最后一个元素后,如果和数组1差值变小了, *就继续减去尾元素,直到满足差值最小,得到本轮最优解; 用该值和下一轮进行比较, *如果下一轮差值更小,则继续切割数组,找更下一轮,直到不满足,然后根据i,j位置输出数组元素; */ int main(){ int n, m, arr1[10], arr2[10], sum1 = 0, sum2 = 0; int res; scanf("%d %d", &n, &m); for(int i = 0; i < n; i++){ scanf("%d", &arr1[i]); sum1 += arr1[i]; } for(int j = 0; j < m; j++){ scanf("%d", &arr2[j]); sum2 += arr2[j]; } int min = *(compute(arr2, m, 0, sum1, sum2)); for(int i = 1; i < m; i++){ res = *compute(arr2, m, i, sum1, sum2); if(abs(res - sum1) < abs(min - sum1)) //比较差值 min = res; else{ i--; //不满足要回溯 int j = *(compute(arr2, m, i, sum1, sum2) + 1); for(int s = i; s <= j; s++) printf("%d ", arr2[s]); break; } } return 0; }
C 解法, 执行用时: 2ms, 内存消耗: 296KB, 提交时间: 2022-03-27
#include<stdio.h> #include<math.h> #include<stdlib.h> void FindMin(int* left, int* right, int* b, int m, int sum) { int difference = 0xffff; int i, j; for (i = 0; i < m; i++) { int tem = -sum; for (j = i; j < m; j++) { tem += b[j]; if (tem > 0) { if (abs(tem) < abs(tem - b[j])) { if (abs(tem) < difference) { difference = abs(tem); *left = i; *right = j; } } if (abs(tem) > abs(tem - b[j])) { if (abs(tem - b[j]) < difference) { difference = abs(tem - b[j]); *left = i; *right = j - 1; } } } } } } int main() { int n, m; scanf("%d %d", &n, &m); int* a = (int*)malloc(sizeof(int) * n); int* b = (int*)malloc(sizeof(int) * m); int i = 0, j = 0; int sum = 0,sumb=0; for (i = 0; i < n; i++) { scanf("%d", &a[i]); sum += a[i]; } for (i = 0; i < m; i++) { scanf("%d", &b[i]); sumb+=b[i]; } if(sumb<sum) { for(i=0;i<m;i++) { printf("%d ",b[i]); } } else { int left = 0, right = 0; FindMin(&left, &right, b, m, sum); for (i = left; i <= right; i++) { printf("%d ", b[i]); } } free(a), free(b); a = NULL, b = NULL; return 0; }
C 解法, 执行用时: 2ms, 内存消耗: 304KB, 提交时间: 2022-03-11
#include<stdio.h> #include<stdlib.h> #include<math.h> int Differ(int *left, int *right,int *p,int n,int d,int sum ) { int and=0; int difference=0xffff; for(int i=0;i<n-d+1;i++) { and=0; for(int j=0;j<d;j++) { and+=p[i+j]; } if(difference>abs(and-sum)) difference=abs(and-sum),*left=i,*right=i+d-1; } return difference; } int main() { int n=0,m=0,sum=0,sumb=0; scanf("%d %d",&n,&m); int *a=(int*)malloc(n*sizeof(int)); int *b=(int*)malloc(m*sizeof(int)); for(int i=0;i<n;i++) { scanf("%d",&a[i]); sum+=a[i]; } getchar(); for(int i=0;i<m;i++) scanf("%d",&b[i]); int left=0,right=0; int sum_left=0,sum_right=0; int difference=0xffff,sum_difference=0xffff; for(int i=0;i<m;i++) { sum_difference=Differ(&sum_left,&sum_right,b,m,i+1,sum); if((sum_difference<difference)||((sum_difference==difference)&&(sum_left<left))) left=sum_left,right=sum_right,difference=sum_difference; } for(int i=left;i<(right+1);i++) printf("%d ",b[i]); }
C 解法, 执行用时: 2ms, 内存消耗: 312KB, 提交时间: 2022-05-08
#include<stdio.h> int main() { int i, j, t, n, m, sum = 0, flag = 9999, temp = 0, l = 0, r = 0; scanf("%d %d", &n, &m);//数组a,b的长度 // getchar(); int b[100] = { 0 }; for (i = 0; i < n; i++) { scanf("%d",&j); sum += j; }//sum是数组a各元素之和 // getchar(); for (i = 0; i < m; i++) { scanf("%d", &b[i]); }//存入数组b for (j = 0; j < m; j++) {//数组中第j个数 temp = 0; for (i = j; i < m; i++) {//第j个数和它后面的所有数 temp += b[i]; if (temp == sum) {//子数组之和恰好等于数组a的和,输出子数组 for ( t = j; t <= i; t++) return 0; } else if (temp > sum) {//子数组之和大于数组a的和,且子数组更接近数组a if (temp - sum < flag) { l = j; r = i; flag = temp - sum; }//记录此子数组的开始点和结束点 } else {//同上 if (sum - temp < flag) { l = j; r = i; flag = sum - temp; } } } } for ( t = l; t <= r; t++) { printf("%d ", b[t]); } }