题目传送门
【题目大意】
有$n$场比赛,给出你的对手每匹马的能力值和你的每匹马的能力值,每场比赛胜利则得两分,平手得一分,输了不得分。求$n$场比赛后你的最大和最小得分。
【思路分析】
设$a$数组记录对手的马的能力值,$b$数组记录你的马的能力值,将两个数组从小到大排序。
首先分析最大得分,我们有这样的贪心策略:
1.如果当前状态下$a_{max}
2.如果当前状态下$a_{min}
3.当上面两个条件都不满足时,就用$b_{min}$去和$a_{max}$比,然后继续上面的步骤
最后即可得出最大得分$ans_1$
对于最小得分,我们可以发现一个规律:无论如何,$n$场比赛结束后两人的总得分为$2*n$,那么可以用上面的方法求出对手的最大得分$ans$,那么最小得分即为$ans_2=2*n-ans$
【代码实现】
1 #include
2 #include
3 #include
4 #include
5 #include
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]2;
37 while(la<=ra&&lb<=rb&&a[la]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 }
代码戳这里