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;
}