zoukankan      html  css  js  c++  java
  • 火柴排队(归并)

     NOIP2013提高组day1 第二题

    思路

    其中 Σ(ai-bi)^2=Σ(ai^1+bi^2-2aibi)差值最小的意思就是Σaibi最大,即顺序和最大

    可先把两盒火柴分别排序,然后用一个数组把一盒火柴的编号保存为相对应的另一盒火柴的下标,再对该数组归并求逆序对

    最小交换次数即求逆序对,也可用归并或树状数组来求

    以下是归并的代码O(3logn)

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #define LL long long
    using namespace std;
    const int maxx=100001;
    int n,ys=99999997;
    LL ans;
    struct xx{
      int x,num;
    }a[maxx],b[maxx];
    int c[maxx],d[maxx];
    bool cmp(const xx a,const xx b)
    {
      return a.x<b.x;
    }
    void merge(int l,int r)
    {
      if(l==r)return;
      int mid=(l+r)>>1;
      merge(l,mid);
      merge(mid+1,r);
      int i=l,j=mid+1,k=l;
      while(i<=mid&&j<=r)
      {
        if(c[i]>c[j]){        //逆序对只算向左移的数字
           ans=(ans+mid-i+1)%ys;
          d[k++]=c[j++];
        }
        else   d[k++]=c[i++];
      }


      while(i<=mid)d[k++]=c[i++];
      while(j<=r) d[k++]=c[j++];


      for(int i=l;i<=r;i++)
      c[i]=d[i];
    }
    int main()
    {
      cin>>n;
      for(int i=1;i<=n;i++)
        scanf("%d",&a[i].x),a[i].num=i;
      for(int i=1;i<=n;i++)
        scanf("%d",&b[i].x),b[i].num=i;


      sort(a+1,a+n+1,cmp);
      sort(b+1,b+n+1,cmp);


      for(int i=1;i<=n;i++)  c[a[i].num]=b[i].num;


      merge(1,n);


      cout<<ans%ys;
      return 0;
    }

  • 相关阅读:
    图像滤波
    直方图histeq
    直方图
    基于灰度变换的图像增强
    图像增强
    图像旋转和缩放
    图像点运算
    像素的连接与联通
    程序员进阶之算法练习(一)
    RxSwift 系列(二)
  • 原文地址:https://www.cnblogs.com/lwhinlearning/p/5661427.html
Copyright © 2011-2022 走看看