现在有两个长度为n的排列p和s。要求通过交换使得p变成s。交换 pipi 和 pjpj 的代价是|i-j|。要求使用最少的代价让p变成s。
Input单组测试数据。
第一行有一个整数n (1≤n≤200000),表示排列的长度。
第二行有n个范围是1到n的整数,表示排列p。每个整数只出现一次。
第三行有n个范围是1到n的整数,表示排列s。每个整数只出现一次。Output输出一个整数,表示从排列p变到s最少要多少代价。
Sample Input
样例输入1 4 4 2 1 3 3 2 4 1
Sample Output
样例输出1 3 题目大意 :给你一初始组序列和一组既定序列,求从初始序列到既定序列所用最小的|i-j|值的和。 题目分析 :
考虑排列p中最后一个位置不对的数字,不妨设为pj,他的目标位置是pi,那么如果p[i+1,j]中有任意一个数的目标是pk(k<i),那么可以进行必要交换。
假设没有这样的一个数字使得他的目标是pk,一共有(j-i-1)个数,(j-i-2)个空,根据鸽巢原理,显然不存在这样的情况。
也就是说,对于排列p中最后一个位置不对的数字pj,目标位置是pi,pi总能在p[i+1,j]中找到一个数字pk,使得它们交换之后到目标的距离都减小了。
题目收获 :仍存疑问。
AC代码:
#include <iostream> #include <cstdio> #include <math.h> using namespace std; int ans[200005]; int main() { int n, x; long long sum = 0; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &x), ans[x] = i; for (int i = 1; i <= n; i++) { int y = 0; scanf("%d", &y); sum += abs(ans[y] - i); } printf("%lld\n", sum / 2); }
时间: 2024-10-14 15:59:46