1 solutions
-
0
题面描述:
给定两个长度为 的整数数组 和 ,可以通过交换数组 中任意两个元素来使得所有下标 满足 ,每次交换的代价为两个被交换元素下标的和。目标是计算使两个数组在对应位置相等的最小代价和,如果无法通过交换使两个数组相等,则返回 。输入格式为:第一行输入整数 ,表示数组的长度;第二行和第三行分别输入长度为 的数组 和 。输出格式为满足要求的最小代价和,或无法满足时输出 。
思路:
记需要交换的总对数为
swapCount
,其中要交换的数的众数为modeValue
,众数个数为modeCount
,我们分两种情况讨论:-
如果
modeCount <= swapCount / 2
,即众数个数为总数的一半:- 如果
swapCount
为偶数,那么可以直接内部两两交换即可。 - 如果
swapCount
为奇数,记为2*k + 1
,那么最极端的情况也是k
个a
,k
个b
,1
个c
,这样才能拼成一个奇数且满足众数个数不超过总数一半。 - 那么让
k - 1
个a
和k - 1
个b
交换,剩下一个a
、b
和c
,那么至少有两个数可以和nums1[0]
交换,剩下两个交换即可,依然可以内部解决。
- 如果
-
如果
modeCount > swapCount / 2
,只需从前往后找不相等且不等于众数的数与众数交换,最后应满足modeCount <= swapCount / 2
。如不能满足则输出-1
。
代码详解
-
变量定义:
swapCount
:需要交换的元素总个数,即满足nums1[i] == nums2[i]
的那些元素。modeCount
:记录当前众数的数量。modeValue
:当前的众数,即出现最多的数。
-
第一遍遍历数组:
- 统计哪些元素需要被交换(即
nums1[i] == nums2[i]
的那些元素)。 - 更新这些元素的出现次数,并确定当前的众数和众数的数量。
- 统计哪些元素需要被交换(即
-
第二遍遍历数组:
- 如果众数的数量超过了总交换数的一半,需要逐步处理不等于众数的元素,尝试与众数进行交换,直到众数的个数不再超过总数的一半。
-
输出结果:
- 如果通过交换不能满足要求(即
modeCount > swapCount / 2
),则输出-1
。 - 否则,输出最小的交换代价
totalCost
。
- 如果通过交换不能满足要求(即
cpp
#include <bits/stdc++.h> using namespace std; const int MAX_SIZE = 1e5 + 10; int nums1[MAX_SIZE], nums2[MAX_SIZE]; int swapCount; // 需要交换的元素总数 int modeCount; // 众数的个数 int countMap[MAX_SIZE]; // 记录每个数的个数 int modeValue; // 众数的值 signed main() { int n; cin >> n; // 输入数组的长度 for (int i = 0; i < n; i++) cin >> nums1[i]; // 输入第一个数组 for (int i = 0; i < n; i++) cin >> nums2[i]; // 输入第二个数组 int totalCost = 0; // 记录总交换代价 // 统计冲突的元素 for (int i = 0; i < n; i++) { if (nums1[i] == nums2[i]) { totalCost += i; // 当前索引的代价 ++swapCount; // 需要交换的总数增加 ++countMap[nums1[i]]; // 统计当前元素的个数 // 更新众数和众数个数 int currentValue = nums1[i]; if (countMap[currentValue] > modeCount) { modeCount = countMap[currentValue]; modeValue = currentValue; } } } // 处理冲突的元素 for (int i = 0; i < n && modeCount * 2 > swapCount; i++) { int a = nums1[i], b = nums2[i]; // 交换众数与其他不同的元素 if (a != b && a != modeValue && b != modeValue) { totalCost += i; // 计算交换代价 ++swapCount; // 需要交换的总数增加 } } // 判断是否能满足条件 if (modeCount * 2 > swapCount) { cout << -1 << endl; // 无法满足条件 } else { cout << totalCost << endl; // 输出总交换代价 } return 0; }
python
# 定义常量和初始化数组 MAX_SIZE = int(1e5 + 10) nums1 = [0] * MAX_SIZE nums2 = [0] * MAX_SIZE swapCount = 0 # 需要交换的数的总个数 modeCount = 0 # 记录当前众数的个数 countMap = [0] * MAX_SIZE # 记录每个数的出现次数 modeValue = 0 # 当前的众数 # 输入数组长度和元素 n = int(input()) nums1 = list(map(int, input().split())) nums2 = list(map(int, input().split())) totalCost = 0 # 记录总交换代价 # 第一遍遍历数组,统计需要交换的元素 for i in range(n): if nums1[i] == nums2[i]: totalCost += i # 计算交换代价 swapCount += 1 # 交换总数增加 countMap[nums1[i]] += 1 # 记录当前元素的出现次数 currentValue = nums1[i] # 当前元素值 # 更新众数和众数的个数 if countMap[currentValue] > modeCount: modeCount = countMap[currentValue] modeValue = currentValue # 第二遍遍历数组,处理众数 for i in range(n): if modeCount * 2 <= swapCount: break # 如果众数个数不超过总数的一半,结束处理 a = nums1[i] b = nums2[i] # 交换不等于众数的元素 if a != b and a != modeValue and b != modeValue: totalCost += i # 计算交换代价 swapCount += 1 # 交换总数增加 # 输出结果 if modeCount * 2 > swapCount: print(-1) # 无法满足条件 else: print(totalCost) # 输出总交换代价
java
import java.util.Scanner; public class Main { public static final int MAX_SIZE = (int) 1e5 + 10; public static int[] nums1 = new int[MAX_SIZE]; public static int[] nums2 = new int[MAX_SIZE]; public static int swapCount = 0; // 需要交换的元素总个数 public static int modeCount = 0; // 当前众数的个数 public static int[] countMap = new int[MAX_SIZE]; // 记录每个数的出现次数 public static int modeValue = 0; // 当前的众数 public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); // 输入数组长度 // 输入第一个数组 for (int i = 0; i < n; i++) { nums1[i] = sc.nextInt(); } // 输入第二个数组 for (int i = 0; i < n; i++) { nums2[i] = sc.nextInt(); } int totalCost = 0; // 记录总交换代价 // 第一遍遍历数组,统计需要交换的元素 for (int i = 0; i < n; i++) { if (nums1[i] == nums2[i]) { totalCost += i; // 计算交换代价 swapCount++; // 交换总数增加 countMap[nums1[i]]++; // 记录当前元素的出现次数 int currentValue = nums1[i]; // 当前元素值 // 更新众数和众数的个数 if (countMap[currentValue] > modeCount) { modeCount = countMap[currentValue]; modeValue = currentValue; } } } // 第二遍遍历数组,处理众数 for (int i = 0; i < n && modeCount * 2 > swapCount; i++) { int a = nums1[i]; int b = nums2[i]; // 交换不等于众数的元素 if (a != b && a != modeValue && b != modeValue) { totalCost += i; // 计算交换代价 swapCount++; // 交换总数增加 } } // 输出结果 if (modeCount * 2 > swapCount) { System.out.println(-1); // 无法满足条件 } else { System.out.println(totalCost); // 输出总交换代价 } sc.close(); // 关闭输入流 } }
-
- 1
Information
- ID
- 146
- Time
- 1000ms
- Memory
- 256MiB
- Difficulty
- 7
- Tags
- # Submissions
- 266
- Accepted
- 33
- Uploaded By