• 第十八届浙大城市学院程序设计竞赛(同步赛)G


    第十八届浙大城市学院程序设计竞赛(同步赛)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;
    }
    
  • 相关阅读:
    归并排序
    mysql优化
    树结构
    urllib库的使用
    linux常用命令
    mysql慢查询
    支付宝第三方支付
    类型(type)判断
    c语言自带的排序与查找
    多字节与宽字节转换
  • 原文地址:https://www.cnblogs.com/ullio/p/14569318.html
Copyright © 2020-2023  润新知