zoukankan      html  css  js  c++  java
  • codeforces 584 E:映射

    第一步要做的是映射,把目标序列映射成1~n,然后按照这个映射规则把当前序列映射一下

    接下来也稍微有点贪心的意思吧:从1开始放置,位置在它之前的元素,如果找到的元素不在该在的位置,并且和当前元素互换后,找到的元素的目标位置在当前元素的左边,才换

    似乎有点抽象。。。就拿样例来说吧

    映射后当前序列是3 2 4 1

    目标序列是1 2 3 4

    从1开始找,找它之前的,不在该在的位置的元素

    第一个找到3,在1号位置,但是我们不换

    因为现在1在4号位置,换了的话3变到4号位置,3将来还是要往左换才能到达的,这里就有浪费的步骤,继续找

    找到4,在2号位置,我们选择换

    因为换了之后4变到4号位置,满足条件,虽然1没有直接回到1号位置,但是总体来看这是最优的

    不用担心找不到这样的元素。

    因为我们操作的本就是不在正确位置的元素,这样的情况不会成单出现,就好像5在2号位置,那2肯定不在正确的位置。当然,2也可能在5右边,那这样2又占据了一个比5大的位置,该位置的主人又……如此下去肯定要有一个符合要求的元素在5左边才能结束这个循环

    #include"cstdio"
    #include"queue"
    #include"cmath"
    #include"stack"
    #include"iostream"
    #include"algorithm"
    #include"cstring"
    #include"queue"
    #include"map"
    #include"vector"
    #define ll long long
    #define mems(a,b) memset(a,b,sizeof(a))
    #define ls pos<<1
    #define rs pos<<1|1
    
    using namespace std;
    const int MAXN = 2005000;
    const int MAXE = 2050;
    const int INF = 0x3f3f3f3f;
    int f[MAXE],x[MAXE],y[MAXE],pos[MAXE];
    
    struct node{
        int x,y;
        node(){}
        node(int a,int b):x(a),y(b){}
    }ans[MAXN];
    
    int main(){
        int n;scanf("%d",&n);
        for(int i=1;i<=n;i++) scanf("%d",&x[i]);
        for(int i=1;i<=n;i++) scanf("%d",&y[i]);
        for(int i=1;i<=n;i++) f[y[i]]=i;
        for(int i=1;i<=n;i++){
            x[i]=f[x[i]];
            pos[x[i]]=i;
        }
        //for(int i=1;i<=n;i++) cout<<x[i]<<' ';
        int cost=0,step=0,cnt=0;
        for(int i=1;i<=n;i++){  ///number
            if(pos[i]==i) continue;
            while(pos[i]!=i){
                for(int j=1;j<pos[i];j++){   ///pos
                    if(x[j]>=pos[i]){
                        cost+=pos[i]-j;
                        step++;
                        ans[cnt++]=node(j,pos[i]);
                        int t=pos[i];
                        pos[i]=j;pos[x[j]]=t;
                        swap(x[t],x[j]);
                    }
    
                }
            }
        }
        cout<<cost<<endl;
        cout<<step<<endl;
        for(int i=0;i<cnt;i++) cout<<ans[i].y<<' '<<ans[i].x<<endl;
    
        return 0;
    }
  • 相关阅读:
    算法总结之 自然数组的排序
    算法总结之 计算数组最小和
    算法总结之 未排序数组中累加和小于或等于给定值的最长子数组长度
    算法总结之 未排序数组中累加和为给定值的最长子数组系列问题
    wget镜像网站并且下载到指定目录 2012-06-20 19:40:56
    用wget做站点镜像
    【亲测好用!】shell批量采集百度下拉框关键词
    网站发的文章有收录 但是没有排名怎么处理
    NGINX + LUA实现复杂的控制
    Linux下php安装Redis扩展
  • 原文地址:https://www.cnblogs.com/luxiaoming/p/5137652.html
Copyright © 2011-2022 走看看