Description

Input
输入的第一行为一个整数n,表示每支代表队的人数。接下来n行,每行一个整数,描述了n位浙江队的选手的实力值。接下来n行,每行一个整数,描述了你的对手的n位选手的实力值。 20%的数据中,1<=n<=10; 40%的数据中,1<=n<=100; 60%的数据中,1<=n<=1000; 100%的数据中,1<=n<=100000,且所有选手的实力值在0到10000000之间。
Output
包括两个用空格隔开的整数,分别表示浙江队在最好与最坏的情况下分别能得多少分。不要在行末输出多余的空白字符。
Sample Input
2
1
3
2
4
1
3
2
4
Sample Output
2 0
样例说明
我们分别称4位选手为A,B,C,D。则可能出现以下4种对战方式,最好情况下可得2分,最坏情况下得0分。
一 二 三 四
浙江 ??? 结果 浙江 ??? 结果 浙江 ??? 结果 浙江 ??? 结果
一号选手 A C 负 A D 负 B C 胜 B D 负
二号选手 B D 负 B C 胜 A D 负 A C 负
总得分 0 2 2 0
样例说明
我们分别称4位选手为A,B,C,D。则可能出现以下4种对战方式,最好情况下可得2分,最坏情况下得0分。
一 二 三 四
浙江 ??? 结果 浙江 ??? 结果 浙江 ??? 结果 浙江 ??? 结果
一号选手 A C 负 A D 负 B C 胜 B D 负
二号选手 B D 负 B C 胜 A D 负 A C 负
总得分 0 2 2 0
题解:
先排序,然后贪心即可
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n;
int zj[133333], ds[133333], zj1[133333], ds1[133333];
int sta[133333];
bool used[133333], used2[133333];
int deal(int *a, int *b)
{
memset(used, 0, sizeof(used));
memset(used2, 0, sizeof(used2));
int cnt1 = 0;
int cnt2 = 0;
int j = n;
int top = 0;
for (int i = n; i >= 1; i--)
{
while ((j>0) && (a[j] > b[i]))
sta[++top] = j--;
if (top > 0)
{
used[sta[top--]] = used2[i] = 1;
cnt1++;
}
}
int ls = 0;
for (int i = 1; i <= n; i++)
if (!used[i])
zj1[++ls] = a[i];
top = ls = 0;
for (int i = 1; i <= n; i++)
if (!used2[i])
ds1[++ls] = b[i];
j = ls;
for (int i = ls; i >= 1; i--)
{
while ((j>0) && (zj1[j] >= ds1[i]))
top++, j--;
if (top > 0)
top--, cnt2++;
}
return cnt1*2+cnt2;
}
int main()
{
cin >> n;
for (int i = 1; i <= n; i++)
scanf("%d", &zj[i]);
for (int i = 1; i <= n; i++)
scanf("%d", &ds[i]);
sort(zj+1, zj+n+1);
sort(ds+1, ds+n+1);
cout << deal(zj, ds) << " " << n*2-deal(ds, zj);
return 0;
}
/*
10
3
4
3
2
2
2
3
2
1
2
1
2
*/
想要题目数据的请留言