zoukankan      html  css  js  c++  java
  • 火柴排队【逆序对】

    题目链接:https://ac.nowcoder.com/acm/contest/2652/L

    题目大意:

    给两个长度均为 n 的数组,两个数组均为1~n全排列的一种。每次可交换任意一个数组中任意相邻的两个数,求最少多少次交换次数使得两个数组的距离最小。

    距离的定义:若两个数组分别为a[],b[]。则他们的距离为 ∑(a[i] - b[i])²。

    题解思路:

    1.对两个数组进行排序,即得到两个数组的最小距离。(证明起来很麻烦,但我们都能感觉到这样就是最小距离)。

    2.我们想要得到排序后的排列方式,那么就通过排序后对应位置上的数来记录排序前的对应位置。例如排列后,在下标为2的位置上的数依次为 4, 8。那么我们要记录4在排序前处于a数组中的哪个位置,8在排序前处于b数组中的哪个位置。将他们联系起来,作为我们排序后所要达到的目的。对于n个对应数字都如此记录下来,那么对得到的对应数组,计算我们需要交换多少次逆序对使得该数组变成有序,即为答案。

    代码如下:

     1 #include<stdio.h>
     2 #include<algorithm>
     3 using namespace std;
     4 typedef long long ll;
     5 const int MAXN = 1e6 + 100;
     6 const int mod = 99999997;
     7 
     8 int n;
     9 ll ans;
    10 int pos[MAXN], temp[MAXN];
    11 
    12 struct Node
    13 {
    14     int val, id;
    15 }a[MAXN], b[MAXN];
    16 
    17 bool cmp(Node a, Node b)
    18 {
    19     return a.val < b.val; 
    20 }
    21 
    22 void merge(int l, int mid, int r)
    23 {
    24     int i = l, j = mid + 1, k = 0;
    25     while(i <= mid && j <= r)
    26     {
    27         if(pos[i] < pos[j])
    28             temp[++ k] = pos[i ++];
    29         else
    30         {
    31             temp[++ k] = pos[j ++];
    32             ans += (mid - i + 1) % mod;
    33             ans %= mod;
    34         }
    35     }
    36     while(j <= r)
    37         temp[++ k] = pos[j ++];
    38     while(i <= mid)
    39         temp[++ k] = pos[i ++];
    40     k = 0;
    41     for(i = l; i <= r; i ++)
    42         pos[i] = temp[++ k];
    43 }
    44 
    45 void mergesort(int l, int r)
    46 {
    47     if(l < r)
    48     {
    49         int mid = (l + r) / 2;
    50         mergesort(l, mid);
    51         mergesort(mid + 1, r);
    52         merge(l, mid, r);
    53     }
    54 }
    55 
    56 int main()
    57 {
    58     scanf("%d", &n);
    59     for(int i = 1; i <= n; i ++)
    60     {
    61         scanf("%d", &a[i].val);
    62         a[i].id = i;
    63     }
    64     for(int i = 1; i <= n; i ++)
    65     {
    66         scanf("%d", &b[i].val);
    67         b[i].id = i;
    68     }    
    69     sort(a + 1, a + 1 + n, cmp);
    70     sort(b + 1, b + 1 + n, cmp);
    71     for(int i = 1; i <= n; i ++)
    72         pos[a[i].id] = b[i].id;
    73     mergesort(1, n);
    74     printf("%lld
    ", ans);
    75     return 0;
    76 }
    View Code
  • 相关阅读:
    使用Sharepoint Designer 无法打开站点提示错误403 forbidden
    英文Windows系统打开带中文TXT出现乱码
    Linux查看MegaSAS raid卡缓存策略
    PostgreSQL基础CRUD
    PostgreSQL安装(on Windows 10)
    Node.js安装(on Windows 10)
    Spring Data JPA:建立实体类
    Java:类加载
    Spring Data JPA:关联关系(外键)
    MySQL系统化知识概要
  • 原文地址:https://www.cnblogs.com/yuanweidao/p/11922339.html
Copyright © 2011-2022 走看看