CF1573B - Swaps(贪心+数学规律+排序+普及级)
MEXor Mixup(源地址自⇔CF742B)
Problem
You are given two arrays \(a\) and \(b\) of length \(n\) . Array a contains each odd integer from \(1\) to \(2n\) in an arbitrary order, and array \(b\) contains each even integer from \(1\) to \(2n\) in an arbitrary order.
You can perform the following operation on those arrays:
1.choose one of the two arrays
2.pick an index \(i\) from \(1\) to \(n−1\)
3.swap the \(i\)-th and the \((i+1)\)-th elements of the chosen array
Compute the minimum number of operations needed to make array a lexicographically smaller than array \(b\) .
For two different arrays \(x\) and \(y\) of the same length \(n\) , we say that \(x\) is lexicographically smaller than \(y\) if in the first position where \(x\) and \(y\) differ, the array \(x\) has a smaller element than the corresponding element in \(y\) .
Input
Each test contains multiple test cases. The first line contains the number of test cases \(t\ (1≤t≤10^4)\) .
The first line of each test case contains a single integer \(n\ (1≤n≤10^5)\) — the length of the arrays.
The second line of each test case contains \(n\) integers \(a_1,a_2,…,a_n\ (1≤a_i≤2n\) , all \(a_i\) are odd and pairwise distinct) — array \(a\).
The third line of each test case contains \(n\) integers \(b_1,b_2,…,b_n\ (1≤b_i≤2n\) , all \(b_i\) are even and pairwise distinct) — array \(b\).
It is guaranteed that the sum of n over all test cases does not exceed 105.
Output
For each test case, print one integer: the minimum number of operations needed to make array \(a\) lexicographically smaller than array \(b\) .
We can show that an answer always exists.
Example
3
2
3 1
4 2
3
5 3 1
2 4 6
5
7 5 9 1 3
2 4 6 10 8
0
2
3
Note
In the first example, the array \(a\) is already lexicographically smaller than array \(b\) , so no operations are required.
In the second example, we can swap \(5\) and \(3\) and then swap \(2\) and \(4\) , which results in[3,5,1]
and[4,2,6]
. Another correct way is to swap \(3\) and \(1\) and then swap \(5\) and \(1\) , which results in[1,5,3]
and[2,4,6]
. Yet another correct way is to swap \(4\) and \(6\) and then swap \(2\) and \(6\) , which results in[5,3,1]
and[6,2,4]
.
tag:
⇔贪心、⇔数学规律、⇔排序、⇔普及级(*1400)
题意:
对于给定的序列 \(a_{A_1},a_{A_2},…,a_{A_n}\) 、 \(b_{B_1},b_{B_2},…,b_{B_n}\) ,从中取出 \(a_{A_k}\) 与 \(b_{B_k}\) ,使得 \(a_{A_k}<b_{B_k}\) ,且 \(A_k+B_k\) 的值最小。
思路:
可以快速推断出:对于 \(a_{A_k}\) ,找到所有大于它的 \(b_{B_k}\) ,再找到这些 \(b_{B_k}\) 中 \(B_k\) 最小的那个。
例如本题输入样例3,若取 \(a\) 数组的 \(5\) ,则 \(b\) 数组中 \(6\) 、 \(10\) 、 \(8\) 三个元素皆符合题意,而这三个元素中位置最小的是 \(6\) ,故取 \(6\) 。
由于给定的序列为奇偶顺序排列,故我们可以将 \(a\) 序列处理成 1=1,2=3,3=5,…,n=2*n-1
以及 1=2,2=4,…,n=2*n
。
而数组的读入则为:下标存值,元素内容存位置。
则:对于任意的 \(a[k]\) ,我们只需要找到 \(b[k]\) 到 \(b[n]\) 中位置最小的那个即可。而要实现这一目的,只需要倒序遍历处理一遍 \(b\) 数组即可。
AC代码:
//A WIDA Project
#include<bits/stdc++.h>
using namespace std;
const int MAX=1e6+5;
const long long MAX18=1e18+5;
long long T,ans,n,a[MAX],b[MAX],x;
int main(){
ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
cin>>T;
while(T-->0){
cin>>n;
ans=MAX18;
for(int i=1;i<=n;i++){
cin>>x;
a[(x+1)/2]=i;
}
for(int i=1;i<=n;i++){
cin>>x;
b[x/2]=i;
}
for(int i=n-1;i>=1;i--) b[i]=min(b[i],b[i+1]);
for(int i=1;i<=n;i++) ans=min(ans,a[i]+b[i]-2);
if(ans!=MAX18) cout<<ans<<"\n";
else cout<<0<<"\n";
}
return 0;
}
错误次数:2次
原因:误以为 b[0]==a[0]+1
。
文 / WIDA
2021.09.19成文
首发于WIDA个人博客,仅供学习讨论
更新日记:
2021.09.19 成文