【題目大意】
有$n$場比賽,給出你的對手每匹馬的能力值和你的每匹馬的能力值,每場比賽勝利則得兩分,平手得一分,輸了不得分。求$n$場比賽后你的最大和最小得分。
【思路分析】
其實這題原名叫泡泡堂[滑稽.jpg]
設$a$數組記錄對手的馬的能力值,$b$數組記錄你的馬的能力值,將兩個數組從小到大排序。
首先分析最大得分,我們有這樣的貪心策略:
1.如果當前狀態下$a_{max}<b_{max}$,那么就用$b_{max}$去和$a_{max}$比,直到不滿足條件
2.如果當前狀態下$a_{min}<b_{min}$,那么就用$b_{min}$去和$a_{min}$比,直到不滿足條件
3.當上面兩個條件都不滿足時,就用$b_{min}$去和$a_{max}$比,然后繼續上面的步驟
最后即可得出最大得分$ans_1$
對於最小得分,我們可以發現一個規律:無論如何,$n$場比賽結束后兩人的總得分為$2*n$,那么可以用上面的方法求出對手的最大得分$ans$,那么最小得分即為$ans_2=2*n-ans$
【代碼實現】

1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #define g() getchar() 7 #define rg register 8 #define go(i,a,b) for(rg int i=a;i<=b;i++) 9 #define back(i,a,b) for(rg int i=a;i>=b;i--) 10 #define db double 11 #define ll long long 12 #define il inline 13 #define pf printf 14 using namespace std; 15 int fr(){ 16 int w=0,q=1; 17 char ch=g(); 18 while(ch<'0'||ch>'9'){ 19 if(ch=='-') q=-1; 20 ch=g(); 21 } 22 while(ch>='0'&&ch<='9') w=(w<<1)+(w<<3)+ch-'0',ch=g(); 23 return w*q; 24 } 25 const int N=100002; 26 int n,a[N],b[N],ans1,ans2; 27 int main(){ 28 //freopen("","r",stdin); 29 //freopen("","w",stdout); 30 n=fr(); 31 go(i,1,n) b[i]=fr(); 32 go(i,1,n) a[i]=fr(); 33 sort(a+1,a+1+n);sort(b+1,b+1+n); 34 rg int la=1,ra=n,lb=1,rb=n; 35 while(la<=ra&&lb<=rb){ 36 while(la<=ra&&lb<=rb&&a[ra]<b[rb]) ra--,rb--,ans1+=2; 37 while(la<=ra&&lb<=rb&&a[la]<b[lb]) la++,lb++,ans1+=2; 38 if(a[ra]==b[lb]) ans1++; 39 lb++;ra--; 40 } 41 la=lb=1;ra=rb=n; 42 while(la<=ra&&lb<=rb){ 43 while(la<=ra&&lb<=rb&&a[ra]>b[rb]) ra--,rb--,ans2+=2; 44 while(la<=ra&&lb<=rb&&a[la]>b[lb]) la++,lb++,ans2+=2; 45 if(a[la]==b[rb]) ans2++; 46 la++;rb--; 47 } 48 ans2=2*n-ans2; 49 pf("%d %d\n",ans1,ans2); 50 return 0; 51 }