第一眼以为是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 */
时间: 2024-10-13 12:19:28