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
",ans1,ans2);
    return 0; 
}
/*
6
1 4 5 7 9 11
2 3 5 9 10 21
*/
View Code
原文地址:https://www.cnblogs.com/Achenchen/p/7544888.html