赛马
题目描述
QW和TJ分别拥有n匹马,这2n匹马每匹马拥有的能力值都不相同。SB当裁判,负责安排两个人的马匹,分别逐对进行n局比赛,每局比赛能力值高的马匹会赢。如果QW和TJ赢的局数一样,则会发生一个有趣的情况,那就是裁判SB赢得整场比赛。给定QW和TJ拥有的马匹的能力值,问裁判SB是否能够通过安排双方参加每局比赛的马匹,使自己赢得比赛。
输入格式 2080.in
多组数据。
对于每组数据:
第一行是一个整数n.1<=n<=100.
第二行是n个整数,表示QW的马匹的能力值。
第三行是n个整数,表示QW的马匹的能力值。
输入文件的末尾有一个0。
输出格式 2080.out
对于每组测试数据,如果裁判可以通过安排有可能赢得比赛,输出"YES",否则输出"NO".
输入样例 2080.in
4
1 2 7 8
3 4 5 6
2
1 2
3 4
0
输出样例 2080.out
YES
NO
首先,如果n是奇数,那么ans=NO。否则,为了裁判能赢,需要QT刚好输n/2场,赢n/2场。赢和输的场次,是必须要保证的。
由于输赢决定于能力值的大小关系,因此我们应将QW,TJ分别排序,再分析较为直观。
那么如何保证呢?可以尝试画一下实例。
a:2 3 7 9 12 13
b:4 5 6 10 11 14
很显然,去赢的人,自身能力值越大,对手能力值越小,赢面才越大。而去输的人,反正都是要输的,那就干脆输给能力值较高的对手,帮助去赢的人。
因此,我们可以给排序后的马分任务。A[1]~a[n/2]负责去输给b[n/2+1]~b[n]。怎么能保证输面最大呢?将a[1]与b[n/2+1]、a[2]与b[n/2+2]、a[3]与b[n/2+3]这样从左到右一一匹配,输面才能最大。(至于为什么,留给读者自己思考)如果在这种情况下,都会有赢的, 那么ans=NO。
同理,我们将a[n/2+1]~a[n]与b[1]~b[n/2]从左到右一一匹配。如果出现了输的,那么ans=NO。
如果上述情况都没有出现,则ans=YES。
贪心算法,果然是用处广泛。
代码如下:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int MAXN=105;
int n;
int a[MAXN],b[MAXN],v[MAXN];
string ans;
int main()
{
ios::sync_with_stdio(false);
while(1)
{
cin>>n;
if(n==0) break;
for(inti=1;i<=n;i++) cin>>a[i];
for(inti=1;i<=n;i++) cin>>b[i];
sort(a+1,a+1+n);
sort(b+1,b+1+n);
memset(v,0,sizeof(v));
ans="YES";
if(n%2==1) ans="NO";
else
{
inti=1,ok=0;
for(int r=n/2+1;r<=n;r++)//输
{
if(a[i]>b[r])
{
ok=1;
break;
}
i++;
}
if(ok==1) ans="NO";
//赢
i=1;
ok=0;
for(intr=n/2+1;r<=n;r++)
{
if(a[r]<b[i])
{
ok=1;
break;
}
}
if(ok==1) ans="NO";
}
cout<<ans<<endl;
}
return 0;
}