田忌赛马贪心问题

题目描述

    小z 在闲暇之余喜欢玩pk小游戏。
    在游戏中,他和他的对手都有n张卡牌,每张卡牌都有一个魔力值,魔力值高的卡牌一定可以战胜魔力值低的卡牌。双方的一号牌,二号牌......n号牌捉对厮杀,共进行n场pk,每胜一场pk胜利获得2分,平局获得1分,输一场不得分。最终将双方的单回合得分相加得到总分,总分高的一方获得大魔法师的称号。
    在pk开始之前,你可以决定这n张卡牌的出场顺序,即作为几号牌出战,一经确定,不得修改。由于双方都不知道对手卡牌的出战顺序以及每张卡牌的魔力值,所以都是随机安排卡牌的顺序。现在告诉你小z和他的对手的所有卡牌信息,请问小z最高可以获得多少分,最低能得到多少分?

输入

输入的第一行包含一个整数n
接下来的n行,每行一个整数,表示小z的卡牌的魔力值
接下来的n行,每行一个整数,表示对手的卡牌的魔力值
1<=n<=100000,且所有卡牌的魔力值在0到10000000之间。

输出

输出的一行包括两个用空格隔开的整数,分别表示小z的最高与最低得分。
不要在行末输出多余的空白字符

 详情就看代码吧,都注释过了

#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cctype>
#include<map>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
int n, a[100005], b[100005];
int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> a[i];
	for (int i = 1; i <= n; i++)
		cin >> b[i];
	//先从小到大排序
	sort(a + 1, a + 1 + n);
	sort(b + 1, b + 1 + n);
	int x0, xn, y0, yn;
	//x0 y0是数组最差的牌的编号,xn yn是数组最好的牌的编号
	x0 = y0 = 1;
	xn = yn = n;
	int cnt = 0;
	int ans = 0;
	//求 a 数组(小z)最大的得分
	while (++cnt <= n)
	{
		if (a[x0] > b[y0])//a最差的牌大于b最差的牌,a赢一局
		{
			ans += 2;
			x0++, y0++;
		}
		else if (a[x0] < b[y0])//a最差的牌小于b最差的牌,那么a无论如何也会输一局,我们让a最差的去消耗b最好的牌
			yn--, x0++;
		else if (a[x0] == b[y0])//二者最差的牌相等,比较二者最好的牌
		{
			if (a[xn] > b[yn])//a最好的牌大于b最好的牌,a赢一局
			{
				ans += 2;
				xn--, yn--;
			}
			else//a最好的牌小于等于b最好的牌,那么接下来需要比较a最差的和b最好的牌
			{
				if (a[x0] == b[yn])//a最差的和b最好的相等,平局
				{
					ans += 1;
					x0++, yn--;
				}
				else//a最差的小于b最好的牌,就用a最差的消耗b最好的,a输一局
				{
					ans += 0;
					x0++, yn--;
				}
			}
		}
	}
	cout << ans << " ";
	//最小得分就是转化一下比较对象,模仿模仿就行
	x0 = y0 = 1;
	xn = yn = n;
	 cnt = 0;
	 ans = 0;
	 while (++cnt <= n)
	 {
		 //让b尽可能赢
		 if (a[x0] < b[y0])//最差的马慢,a一定输一局
			 x0++, y0++;
		 else if (a[x0] > b[y0])//a最差的快于b最差的,a一定会赢一局
		 {
			 //b无论如何也要输一局,让b最差的消耗a最好的
			 ans += 2;
			 xn--;
			 y0++;
		 }
		 else if(a[x0]==b[y0])
		 {
			 if (a[xn] < b[yn])
				 xn--, yn--;
			 else
			 {
				 if (b[y0] == a[xn])
				 {
					 ans += 1;
					 y0++, xn--;
				 }
				 else
				 {
					 ans += 2;
					 y0++, xn--;
				 }
			 }
		 }
	 }
	 cout << ans;
	return 0;
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值