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("\n");
    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\n", 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数组的任意两个元素,求最小交换次数。

 

posted on 2016-12-12 11:06  stupid_one  阅读(166)  评论(0编辑  收藏  举报

导航