BZOJ 1034 [ZJOI2008]泡泡堂BNB
第一眼以为是SB题,然后充分地发现了自己是SB这个事实。。
可能写得十分丑陋,还是说一下。。
因为会有平分,而且和赢的得分不一样,所以手算几组会发现很多比较玄学的情况。
正确的贪心策略: 把两个数组排序(我是从大到小)。若是我的头大于他的头,则我的ans+2,显然换其他人来赢也不会更优。
若我的尾大于他的尾,我的ans+2,同理任意换不会更优。 若我的头和我的尾都不能赢他了,若我的头和尾相等则直接比赛,
否则,说明我们队任何人都不能赢这个人,于是让我们队最弱的人输给这个人,这样以后 1我们队会一直输下去,无影响 2我的头能在后面赢一个本来不能赢的人,答案不会变劣(若都是打平则不变)。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
typedef long long LL;
using namespace std;
const int maxn=100000+299;
int n,a[maxn],b[maxn],wo,di,l,r,ql,qr,ans1,ans2;
bool cmp(int x,int y) {
return x>y;
}
void solve(int a[],int b[]) {
wo=0,di=0,l=1,r=n,ql=1,qr=n;
while(l<=r) {
if(l==r) {if(a[l]>b[ql]) wo+=2; else if(a[l]==b[ql]) wo++,di++; else di+=2; break;}
if(a[l]>b[ql]) { wo+=2; l++; ql++;}
else {
if(a[r]>b[qr]) {
wo+=2;
r--; qr--;
}
else {
if(a[l]==a[r]) {
if(a[l]==b[ql]) wo++,di++; else di+=2; l++,ql++;
if(a[r]==b[qr]) wo++,di++; else di+=2; r--,qr--;
}
else {
if(a[r]==b[l]) wo++,di++;
else if(a[r]<b[l]) di+=2;
r--; ql++;
}
}
}
}
}
int main()
{
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,cmp); sort(b+1,b+n+1,cmp);
solve(a,b); ans1=wo;
solve(b,a); ans2=di;
printf("%d %d\n",ans1,ans2);
return 0;
}
/*
6
1 4 5 7 9 11
2 3 5 9 10 21
*/