题目来自于博主算法大师的专栏:最新华为OD机试C卷+AB卷+OJ(C++JavaJSPy) https://blog.csdn.net/banxia_frontend/category_12225173.html
题目描述
现有两组服务器A和B,每组有多个算力不同的CPU,其中 A[i] 是 A 组第 i 个CPU的运算能力,B[i] 是 B组 第 i 个CPU的运算能力。
一组服务器的总算力是各CPU的算力之和。
为了让两组服务器的算力相等,允许从每组各选出一个CPU进行一次交换,
求两组服务器中,用于交换的CPU的算力,并且要求从A组服务器中选出的CPU,算力尽可能小。
输入描述
第一行输入为L1和L2,以空格分隔,L1表示A组服务器中的CPU数量,L2表示B组服务器中的CPU数量。
第二行输入为A组服务器中各个CPU的算力值,以空格分隔。
第三行输入为B组服务器中各个CPU的算力值,以空格分隔。
1 ≤ L1 ≤ 10000
1 ≤ L2 ≤ 10000
1 ≤ A[i] ≤ 100000
1 ≤ B[i] ≤ 100000
输出描述
对于每组测试数据,输出两个整数,以空格分隔,依次表示A组选出的CPU算力,B组选出的CPU算力。
要求从A组选出的CPU的算力尽可能小。
备注
- 保证两组服务器的初始总算力不同。
- 答案肯定存在
示例一
输入
2 2
1 1
2 2
输出
1 2
说明:
从 A 组中选出算力为 1 的 CPU,与 B 组中算力为 2 的进行交换,使两组服务器的算力都等于 3。
示例二
输入
2 2
1 2
2 3
输出
1 2
解题思路
解题思路如下:
-
读取输入:
- 首先,从标准输入中读取两组服务器的CPU数量(l1 和 l2)。
- 然后分别读取A组和B组每个CPU的算力值,并计算每组服务器的初始总算力(sumA 和 sumB)。
-
计算目标差值:
- 由于要使两组服务器的算力相等,可以计算两者算力之差并除以2,得到一个目标差值
key
。这样在交换一个CPU之后,可以使两组的算力平衡。
- 由于要使两组服务器的算力相等,可以计算两者算力之差并除以2,得到一个目标差值
-
查找最优交换组合:
- 遍历A组中的每一个CPU,对于每个CPU算力A[i],找到与
key
的差值diff = A[i] - key。 - 再遍历B组中的CPU,查找是否存在一个CPU的算力等于这个差值 diff。
- 如果找到了这样的匹配,即找到了一个可以从A组选出且算力尽可能小、同时能使两组算力平衡的CPU与一个来自B组的CPU进行交换。
- 遍历A组中的每一个CPU,对于每个CPU算力A[i],找到与
-
输出结果:
- 当找到满足条件的交换组合时,立即输出这两个CPU的算力值,并结束程序。
假设了A组的初始算力大于或等于B组的初始算力,因此直接取两组算力之差的一半作为目标差值。如果实际情况需要考虑两组算力可能互为大小关系,则需对目标差值的计算进行修正,确保找到正确且最小的交换算力。不过根据题目描述,答案肯定存在,所以这里采用的简化方法是可行的。
代码
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 主函数入口
int main() {// 读取A组和B组服务器的CPU数量int l1, l2;scanf("%d %d", &l1, &l2);// 定义数组存储A组每个CPU的算力,并初始化A组总算力为0int A[l1];int sumA = 0;// 读取并累加A组所有CPU的算力for (int i = 0; i < l1; i++) {scanf("%d", &A[i]);sumA += A[i]; // 更新A组总算力}// 定义数组存储B组每个CPU的算力,并初始化B组总算力为0int B[l2];int sumB = 0;// 读取并累加B组所有CPU的算力for (int i = 0; i < l2; i++) {scanf("%d", &B[i]);sumB += B[i]; // 更新B组总算力}// 计算使得两组服务器算力相等时,需要交换的CPU算力差值(key)// key = |sumA - sumB| / 2,这里假设sumA > sumB,所以直接取sumA - sumB的一半int key = (sumA - sumB) / 2;// 遍历A组中的每个CPU,寻找与key值最接近且不大于key的CPU算力for (int i = 0; i < l1; i++) {// 计算当前CPU与目标差值的绝对差值int diff = A[i] - key;// 如果这个差值在B组中存在,则找到了符合条件的交换组合for (int j = 0; j < l2; j++) {if (B[j] == diff) { // 当找到一个与diff相等的B组CPU算力时printf("%d %d", A[i], B[j]); // 输出从A组选出的CPU算力和从B组选出的CPU算力return 0; // 找到答案后立即结束程序}}}// 如果未找到合适的交换组合,则理论上不应该执行到这里(根据题设保证存在解)return 0; // 程序正常结束
}
暴力解法
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int sum(int num[], int length) {int total = 0;for (int i = 0; i < length; i++) {total += num[i];}return total;
}
void swap(int arrayA[], int arrayB[], int indexA, int indexB) {// 临时变量用于存储值int temp = arrayA[indexA];arrayA[indexA] = arrayB[indexB];arrayB[indexB] = temp;
}
int main() {int l1, l2;scanf("%d %d", &l1, &l2);int A[l1];for (int i = 0; i < l1; i++) {scanf("%d", &A[i]);}int B[l2];for (int i = 0; i < l2; i++) {scanf("%d", &B[i]);}int diff;for (int i = 0; i < l1; i++) {for (int j = 0; j < l2; j++) {swap(A, B, i, j);diff = sum(A, l1) - sum(B, l2);if (diff != 0) {swap(A, B, i, j);} else {printf("%d %d\n", B[j], A[i]);//因为B[j]和 A[i]交换了,所以输出的是原来的A[i],B[j]return 0;}}}return 0;
}