码迷,mamicode.com
首页 > 其他好文 > 详细

火柴排队【逆序对】

时间:2019-11-24 15:29:09      阅读:41      评论:0      收藏:0      [点我收藏+]

标签:scan   const   contest   include   lse   void   mes   定义   最小   

题目链接: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\n", ans);
75     return 0;
76 }
View Code

 

火柴排队【逆序对】

标签:scan   const   contest   include   lse   void   mes   定义   最小   

原文地址:https://www.cnblogs.com/yuanweidao/p/11922339.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!