1. 程式人生 > >BZOJ 1034 [ZJOI2008]泡泡堂BNB

BZOJ 1034 [ZJOI2008]泡泡堂BNB

很多 using spl 平分 可能 one 否則 大於 long

題目傳送門

第一眼以為是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 */
View Code

BZOJ 1034 [ZJOI2008]泡泡堂BNB