[ZJOI 2008]泡泡堂BNB

Description

题库链接

双方 (n) 人,给出每人的战斗力,赢一场加 (2) 分,平局 (1) 分,失败不得分。求最大和最小的得分。

(1leq nleq 100000)

Solution

田忌赛马。贪心策略及证明可以参考链接

最小得分就相当于 (2n-) 对方最大得分。交换再做一次贪心即可。

Code

//It is made by Awson on 2018.2.27
#include <bits/stdc++.h>
#define LL long long
#define dob complex<double>
#define Abs(a) ((a) < 0 ? (-(a)) : (a))
#define Max(a, b) ((a) > (b) ? (a) : (b))
#define Min(a, b) ((a) < (b) ? (a) : (b))
#define Swap(a, b) ((a) ^= (b), (b) ^= (a), (a) ^= (b))
#define writeln(x) (write(x), putchar('
'))
#define lowbit(x) ((x)&(-(x)))
using namespace std;
const int N = 100000;
void read(int &x) {
    char ch; bool flag = 0;
    for (ch = getchar(); !isdigit(ch) && ((flag |= (ch == '-')) || 1); ch = getchar());
    for (x = 0; isdigit(ch); x = (x<<1)+(x<<3)+ch-48, ch = getchar());
    x *= 1-2*flag;
}
void print(int x) {if (x > 9) print(x/10); putchar(x%10+48); }
void write(int x) {if (x < 0) putchar('-'); print(Abs(x)); }

int n, a[N+5], b[N+5];
bool comp(const int &a, const int &b) {return a > b; }

int cal(int* a, int* b) {
    int l1 = 1, l2 = 1, r1 = n, r2 = n, ans = 0;
    while (l1 <= r1) { 
    if (a[r1] > b[r2]) ans += 2, --r1, --r2;
    else if (a[l1] > b[l2]) ans += 2, ++l1, ++l2;
    else ans += (a[r1] == b[l2]), --r1, ++l2;
    }
    return ans;
}
void work() {
    read(n);
    for (int i = 1; i <= n; i++) read(a[i]); sort(a+1, a+n+1, comp);
    for (int i = 1; i <= n; i++) read(b[i]); sort(b+1, b+n+1, comp);
    write(cal(a, b)), putchar(' '), writeln(2*n-cal(b, a));
}
int main() {
    work(); return 0;
}
原文地址:https://www.cnblogs.com/NaVi-Awson/p/8478073.html