• E、CSL 的魔法 【模拟】 (“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛)


    题目传送门:https://ac.nowcoder.com/acm/contest/551#question

    题目描述 

    有两个长度为 n 的序列,a0,a1,,an1a0,a1,…,an−1和 b0,b1,,bn1b0,b1,…,bn−1。CSL 有一种魔法,每执行一次魔法,可以任意挑选一个序列并任意交换序列中两个元素的位置。CSL 使用若干次魔法,得到最终的序列 a 和 b,并且想要让 a0b0+a1b1++an1bn1a0b0+a1b1+…+an−1bn−1的值最小化。求解 CSL 至少使用多少次魔法,能够达到最小化的目标。

    输入描述:

    第一行有一个整数 n,表示序列的长度。

    接下来两行,每行有 n 个整数,分别表示初始序列 a 和 b。

    输入数据保证每个序列里的数两两不同。
     
    2n1052≤n≤105
    1ai,bi1091≤ai,bi≤109

    输出描述:

    在一行输出一个整数,表示最少使用的魔法次数。
    示例1

    输入

    复制
    2
    1 2
    1 2

    输出

    复制
    1
    示例2

    输入

    复制
    2
    1 2
    2 1

    输出

    复制
    0

    解题思路:

    注意一个bug点即可:

    给出的a b 序列的数不一定相同。

    所以对于 两个序列都要进行排序,然后map映射一下原序列每个数对应的位置,每个数的排名。

    然后以其中一个序列为参考,扫一遍,最大的匹配另一个序列里最小的,不能匹配则交换序列里两个数的位置。

    AC code:

     1 #include <bits/stdc++.h>
     2 #define INF 0x3f3f3f3f
     3 #define LL long long
     4 #define inc(i, j, k) for(int i = j; i <= k; i++)
     5 #define rep(i, j, k) for(int i = j; i < k; i++)
     6 #define mem(i, j) memset(i, j, sizeof(i))
     7 #define gcd(i, j) __gcd(i, j)
     8 using namespace std;
     9 const int MAXN = 2e5+10;
    10 map<int, int>ida, idb, xa, xb;
    11 int a[MAXN], b[MAXN], tpa[MAXN], tpb[MAXN];
    12 
    13 bool cmp(int a, int b)
    14 {
    15     return a > b;
    16 }
    17 int N;
    18 
    19 int main()
    20 {
    21     scanf("%d", &N);
    22     inc(i, 1, N){ scanf("%d", &a[i]); tpa[i] = a[i]; xa[a[i]] = i;}
    23     inc(i, 1, N){ scanf("%d", &b[i]); tpb[i] = b[i]; xb[b[i]] = i;}
    24     sort(tpa+1, tpa+1+N);
    25     inc(i, 1, N) ida[tpa[i]] = i;
    26     sort(tpb+1, tpb+1+N, cmp);
    27     inc(i, 1, N) idb[tpb[i]] = i;
    28     int ans = 0;
    29     inc(i, 1, N)
    30     {
    31         if(ida[a[i]] != idb[b[i]]){
    32             ans++;
    33             int nxtb = tpb[ida[a[i]]];
    34             int nxt = xb[nxtb];
    35             xb[b[i]] = nxt;
    36             xb[b[nxt]] = i;
    37             swap(b[i], b[nxt]);
    38         }
    39     }
    40 
    41     printf("%d
    ", ans);
    42     return 0;
    43 }
    View Code
  • 相关阅读:
    交叉编译环境软件搭建
    (C)struct结构体
    (C)字节对齐#pragma pack()
    常用bluetooth协议
    (C/C++)register关键字
    Android学习
    (C)*p++和*++p区别
    java文件末尾追加内容的两种方式
    java1.7集合源码阅读: Stack
    java1.7集合源码阅读: Vector
  • 原文地址:https://www.cnblogs.com/ymzjj/p/10665243.html
Copyright © 2020-2023  润新知