• L 裁纸片 贪心 + 模拟


    https://biancheng.love/contest-ng/index.html#/123/problems

    如果只是输出最小的值,那么好办,a升序,b降序,这样是最优的。

    但是需要次数,这就麻烦了。

    但是注意到它说数字互不相同。

    那么,用个数组book[a[i]]表示a[i]需要匹配的是那个数字,就是a数组的最小值,需要匹配b数组的最大值。

    然后从原数组中模拟。

    因为可能并不需要全部都排序的,本来就一一对应的话,就不需要排。

    比如

    2 1

    1 2

    也是不需要排的。

    然后就是模拟了,对于如果不是一一对应的每一个数,就去找一个和它对应的,交换就行了。只有这样的解了。

    1
    3
    1 2 3
    2 1 3

    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <assert.h>
    #define IOS ios::sync_with_stdio(false)
    using namespace std;
    #define inf (0x3f3f3f3f)
    typedef long long int LL;
    
    
    #include <iostream>
    #include <sstream>
    #include <vector>
    #include <set>
    #include <map>
    #include <queue>
    #include <string>
    const int maxn = 3e6 + 20;
    LL a[maxn];
    LL b[maxn];
    LL tocmpa[maxn];
    LL tocmpb[maxn];
    int book[maxn];
    int pos[maxn];
    const int fix = 1e6;
    void work() {
        int n;
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            scanf("%lld", &a[i]);
            tocmpa[i] = a[i] + fix;
        }
        for (int i = 1; i <= n; ++i) {
            scanf("%lld", &b[i]);
            tocmpb[i] = b[i] + fix;
            pos[tocmpb[i]] = i;
        }
        sort(a + 1, a + 1 + n);
        sort(b + 1, b + 1 + n, greater<LL>());
        LL ans = 0;
        for (int i = 1; i <= n; ++i) {
            ans += a[i] * b[i];
        }
        for (int i = 1; i <= n; ++i) {
            book[a[i] + fix] = b[i] + fix;
        }
        int anstime = 0;
    //    for (int i = 1; i <= n; ++i) {
    //        printf("%d ", pos[book[tocmpa[i]]]);
    //    }
    //    printf("
    ");
        for (int i = 1; i <= n; ++i) {
            if (book[tocmpa[i]] == tocmpb[i]) continue;
            anstime++;
            int wan = book[tocmpa[i]];
            int cur = tocmpb[i];
            int poswan = pos[wan];
            int poscur = pos[cur];
            swap(tocmpb[poswan], tocmpb[poscur]);
            swap(pos[wan], pos[cur]);
        }
        printf("%lld %d
    ", ans, anstime);
    }
    
    int main() {
    #ifdef local
        freopen("data.txt", "r", stdin);
    //    freopen("data.txt", "w", stdout);
    #endif
        int t;
        scanf("%d", &t);
        while (t--) work();
        return 0;
    }
    View Code

    这题的原题其实是:

    给定两个数组,要使得b数组变成a数组,每次可以交换b数组的任意两个元素,求最小交换次数。

  • 相关阅读:
    257. Binary Tree Paths
    324. Wiggle Sort II
    315. Count of Smaller Numbers After Self
    350. Intersection of Two Arrays II
    295. Find Median from Data Stream
    289. Game of Life
    287. Find the Duplicate Number
    279. Perfect Squares
    384. Shuffle an Array
    E
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6163694.html
Copyright © 2020-2023  润新知