Game of Credit Cards (Codeforces-777B)

题目链接:

http://codeforces.com/problemset/problem/777/B

B. Game of Credit Cards
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

After the fourth season Sherlock and Moriary have realized the whole foolishness of the battle between them and decided to continue their competitions in peaceful game of Credit Cards.

Rules of this game are simple: each player bring his favourite n-digit credit card. Then both players name the digits written on their cards one by one. If two digits are not equal, then the player, whose digit is smaller gets a flick (knock in the forehead usually made with a forefinger) from the other player. For example, if n = 3, Sherlock's card is 123and Moriarty's card has number 321, first Sherlock names 1 and Moriarty names 3 so Sherlock gets a flick. Then they both digit 2 so no one gets a flick. Finally, Sherlock names 3, while Moriarty names 1 and gets a flick.

Of course, Sherlock will play honestly naming digits one by one in the order they are given, while Moriary, as a true villain, plans to cheat. He is going to name his digits in some other order (however, he is not going to change the overall number of occurences of each digit). For example, in case above Moriarty could name 123 and get no flicks at all, or he can name 23 and 1 to give Sherlock two flicks.

Your goal is to find out the minimum possible number of flicks Moriarty will get (no one likes flicks) and the maximum possible number of flicks Sherlock can get from Moriarty. Note, that these two goals are different and the optimal result may be obtained by using different strategies.

Input

The first line of the input contains a single integer n (1 ≤ n ≤ 1000) — the number of digits in the cards Sherlock and Moriarty are going to use.

The second line contains n digits — Sherlock's credit card number.

The third line contains n digits — Moriarty's credit card number.

Output

First print the minimum possible number of flicks Moriarty will get. Then print the maximum possible number of flicks that Sherlock can get from Moriarty.

Examples
input
3
123
321
output
0
2
input
2
88
00
output
2
0

题目大意:

按照测试数据说吧,这样好理解。第一行输入n,接下来输入两个长度为n的字符串a[n],b[n]。第一个人从第一个字符串中 从头开始 按照顺序拿一个数字,第二个人按照顺序从第二个子串中拿一个数字(第二个人比较淘气,不按比赛规则来,他想拿那个数字就拿哪个数字,每个数字只能拿一次)。然后比较这两个人的拿到的数字大小,数字大的那个人 打 数字小的那个人一下,如果两个数字相等的话,谁也不打谁。题目要求输出 第二个人被第一个人打次数最小值 和 第二个人打第一个人次数最大值 。

解题思路:

(1)求第二个人被打的最少次数:

从第一个字符串的第一位开始a[i],如果能在第二个字符串中找到b[j]>=a[i],那么说明第一个人可以不挨打,如果找不到,那么让第二个人拿出最小值的出来(因为大的数下一次可能会用上,既然这一次避免不了挨打,就拿最小的数当“替死鬼”),然后min++。然后遍历a[]数组的第二位数字......最后输出min值即可。

(2)求第二个人打第一个人的最多次数:

还是从第一个字符串的第一位开始a[i],如果在第二个字符串中能够找到b[j]>a[i],说明第二个人要打第一个人一次,max++,然后继续遍历......最后输出max值。

代码:

#include<iostream>
#include<map>
#include<algorithm>
#include<string>
using namespace std;
int main()
{
    int n,flag;
    string a,b;
    while(cin>>n)
    {
        map<int,int>A;   //保存第一个字符串中 每个数字 的个数
        map<int,int>B;   //保存第二个字符串中 每个数字 的个数
        map<int,int>C;   //保存第二个字符串中 每个数字 的个数,因为要计算min和max,要计算两次,而计算一次后值将改变,所以再次记录
        cin>>a>>b;
        for(int i=0;i<=n-1;i++)
            A[a[i]]++;   //第一个字符串中对应的数字个数+1
        for(int i=0;i<=n-1;i++)
        {
            B[b[i]]++;   //第二个字符串中对应数字个数+1
            C[b[i]]++;   //第二个字符串中对应数字个数+1
        }
        sort(b.begin(),b.end());   //将第二个字符串从小到大排序
        int min=0;   //
        for(int i=0;i<=n-1;i++)   //从第一个字符串的开头开始遍历
        {
            flag=0;
            for(int j=0;j<=n-1;j++)
            {
                if(b[j]>=a[i]&&B[b[j]]>0)   //说明可以不挨打
                {
                    B[b[j]]--;   //对应数字的个数要-1,因为用过了
                    flag=1;   //把flag标记为1
                    break;
                }
            }
            if(flag==0)   //说明这一次要挨打
            {
                min++;   //挨打个数+1
                for(int i=0;i<=n-1;i++)   //找出a字符串中的最小值 做 “替死鬼”
                {
                    if(B[b[i]]>0)
                    {
                        B[b[i]]--;
                        break;
                    }
                }
            }
        }
        //下面计算第二个大地一个人次数最大值与上面的计算方法差不多,这里不做解释
        int max=0;
        for(int i=0;i<=n-1;i++)
        {
            flag=0;
            for(int j=0;j<=n-1;j++)
            {
                if(b[j]>a[i]&&C[b[j]]>0)
                {
                    max++;
                    C[b[j]]--;
                    flag=1;
                    break;
                }
            }
            if(flag==0)
            {
                for(int i=0;i<=n-1;i++)
                {
                    if(C[b[i]]>0)
                    {
                        C[b[i]]--;
                        break;
                    }
                }
            }
        }
        cout<<min<<endl<<max<<endl;
    }
    return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值