zoukankan      html  css  js  c++  java
  • 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数组的任意两个元素,求最小交换次数。

  • 相关阅读:
    阅读笔记(四)——《代码整洁之道》1
    阅读笔记(一)——《需求工程——软件建模与分析》一
    数据提取
    HIVE数据清洗练习
    第八周hadoop-MapReduce
    小程序新增页面导航栏
    个人课程总结
    第十六周总结

    排序
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6163694.html
Copyright © 2011-2022 走看看