第十八届浙大城市学院程序设计竞赛(同步赛)G
大意
略。。
思路
很不错的题。。可惜我负数做下标没注意调了半天(
首先,看到两个长度相同的排列,就要想到有序化。
题中给了 (a) , (b) ,不妨假设存在一种函数关系,使 (f(b_i) = i)
将原序列变换,设 (c=f(a)) 和 (d=f(b)={1,2,3,...,n})
(如果观察改变前后 (a_i) 和对应 (b_i) 的位置差,你会发现这是完全不变的,因为值相等的位置,变换前后仍然相等)
容易得到,改变后的序列与原序列的答案一定是一致的。
再进行一步变形,令 (e_i = c_i - d_i)
不难发现实际 (e_i) 的值就是 (c_{i}) 与 (i) 的位置差值,也就是距离匹配位置的距离。
所以,(e) 中相同的数是一组,它们在进行移动操作 (-e_i) 次后正好与 (d) 中相应的数对应上。
大于零的数不用考虑,因为修改只能把数向前移动,而被移到结尾的数已经会被修改。
答案就是 (n-max(the num of same e_i)) ((c_ileq 0))
代码
#include <map>
#include <set>
#include <cmath>
#include <queue>
#include <cstdio>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define ll long long
#define ull unsigned long long
#define cint const int&
#define Pi acos(-1)
const int mod = 1e9+7;
const int inf_int = 0x7fffffff;
const ll inf_ll = 0x7fffffffffffffff;
const double ept = 1e-9;
int n;
int a[1001000];
int to[1001000];
int sum[1001000];
int main() {
int r;
cin >> n;
for(int i=1; i<=n; i++) cin >> a[i];
for(int i=1; i<=n; i++) cin >> r,to[r] = i;
int mx = -inf_int;
for(int i=1; i<=n; i++) a[i] = to[a[i]] - i;
for(int i=n; i>=1; i--) if(a[i] <= 0) ++sum[-a[i]], mx = max(mx, -a[i]);
int ans = n;
for(int i=0; i<=mx; i++) ans = min(ans, n-sum[i]);
cout << ans << endl;
return 0;
}