ZJOI2008 泡泡堂

题目链接:戳我

看来我是要退役了,贪心都不会写了QAQ

开始以为以小博大就行了,只要让较弱的尽可能去牺牲就行。但是明显如果弱的可以战胜对方弱的,让他去跟强的打这一场就白输了(而且那个它本来可以对付的对方弱的,还有胜利的可能)。

之后又想尽量用小的去战胜它能胜利的小的,但是这样也不行,一来是有平局的出现不好处理,二来是复杂度也有点问题。

最后才知道应该这样子做——

先用当前还剩下来的最弱的和对方最弱的比,如果赢了那自然是好的。
如果没有赢,那么这两分是被对方稳赚了,现在我们要考虑让谁拿这个分。
一个考虑是送给对方目前最强的。
但是这里需要判断一点,就是如果自己现在最强的可以战胜对方最强的,那肯定是要赢下这一场。它的分不能送给对方最强的,应该送给别的人(比如说游戏进行到后来己方会遇到不可战胜的对手,送给这个人就行了)(但是由于我们不知道到底会送给谁,所以只需要记录自己能胜利的场次即可。)
如果己方最强战胜不了对方最强,那么我们把这个分送给对方最强(但是还需要判断一下是否会平局,这样还会多出来一分要加QAQ)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 100010
using namespace std;
int n;
int a[MAXN],b[MAXN];
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("ce.in","r",stdin);
    #endif
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&a[i]);
    for(int i=1;i<=n;i++) scanf("%d",&b[i]);
    sort(&a[1],&a[n+1]);
    sort(&b[1],&b[n+1]);
    int ans=0;
    int l1=1,r1=n,l2=1,r2=n;
    while(l1<=r1&&l2<=r2)
    {
        if(a[l1]>b[l2]) ans+=2,l1++,l2++;
        else
        {
            if(a[r1]>b[r2]) ans+=2,r1--,r2--;
            else ans+=a[l1]==b[r2],l1++,r2--;
        }
    }
    printf("%d ",ans);
    swap(a,b);
    ans=0,l1=1,r1=n,l2=1,r2=n;
    while(l1<=r1&&l2<=r2)
    {
        if(a[l1]>b[l2]) ans+=2,l1++,l2++;
        else
        {
            if(a[r1]>b[r2]) ans+=2,r1--,r2--;
            else ans+=a[l1]==b[r2],l1++,r2--;
        }
    }
    printf("%d\n",2*n-ans);
    return 0;
}
posted @ 2019-05-22 23:54  风浔凌  阅读(124)  评论(0编辑  收藏  举报