akoj-1291-决战21点

Description
21点是一个非常有趣的游戏,游戏规则是两个人各自抽取若干张牌后 看谁点数更大(但不能超过21点,否则算0)如果两个点数相等,则庄家获胜
2 3 4 5 6 7 8 9点数都是各自的数码
10 J Q K 都是10点
A既可以当成11点,也可以当成1点。

Input
每组数据包括 n m表示庄家和闲家的牌总数
接下来两行分别表示庄家和闲家的牌

Output
输出比分以及庄家赢(HOST WIN)还是闲家赢(GUEST WIN)

Sample Input
2 3
A J
A A Q
2 6
Q J
A A A A 7 K

Sample Output
21 vs 12 HOST WIN
20 vs 21 GUEST WIN

实际上这道题是当时校赛最亏的一道题了,现在写一遍感觉真心不难,很基础,当时看完题目以为不太好写,说留最后搞,然后比完之后也没兴趣去看这题了,就一直放那了,今天点点看到了,写了一下,不难,唉,失误失误。
思路简单描述一下吧:首先输入后把那些固定的牌的点数先加上,然后再来处理A的问题,怎么处理?实际上题意就是这个A到底是作为1还是11,那我们就枚举,先0张A作为1,其他剩的就为11,一直到一半就行了,然后找出<=21点中的最大和,好,这就是你的点数。实际庄家和闲家的处理是一样的,把代码再复制一遍即可,对于超过21点的,置为0即可。

AC Code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace AK1291 {
    /// 
    /// 一开始没考虑最小和超过21点为0,WA了一次,然后加上就AC了
    /// 感觉这题真不难,不就几张当1,剩下当11嘛,你说比赛的时候咋就不写呢,不能忍
    /// what's the fuck
    /// 
    class Program {
        static void Main(string[] args) {
            string s;
            while ((s = Console.ReadLine()) != null) {
                string[] ss = s.Split();
                int n = int.Parse(ss[0]), m = int.Parse(ss[1]);
                string[] a = Console.ReadLine().Split();
                string[] b = Console.ReadLine().Split();
                int acount = 0, bcount = 0;//表示a和b中有多少个A
                int asum = 0, bsum = 0;
                for (int i = 0; i < n; i++) {
                    if (a[i].Equals("A")) acount++;
                    else {
                        if (a[i].Equals("J") || a[i].Equals("Q") || a[i].Equals("K") || a[i].Equals("10"))
                            asum += 10;
                        else asum += int.Parse(a[i]);
                    }
                }
                for (int i = 0; i < m; i++) {
                    if (b[i].Equals("A")) bcount++;
                    else {
                        if (b[i].Equals("J") || b[i].Equals("Q") || b[i].Equals("K") || b[i].Equals("10"))
                            bsum += 10;
                        else bsum += int.Parse(b[i]);
                    }
                }
                //ok   前面处理完其他数据了,下面只要加上多少个1还是11了
                int amax = asum, bmax = bsum;
                if (asum + acount > 21) amax = 0;//这些牌最小和都超过21了,置0
                else {
                    for (int i = 0; i <= acount; i++) {
                        int aans = i + (acount - i) * 11;//i张牌当做1,acount-i就当做11
                        if (aans + asum <= 21 && aans + asum > amax) amax = aans + asum;//找到符合条件的最大牌的和
                    }
                }
                if (bsum + bcount > 21) bmax = 0;
                else {
                    for (int i = 0; i <= bcount; i++) {
                        int bans = i + (bcount - i) * 11;
                        if (bans + bsum <= 21 && bans + bsum > bmax) bmax = bans + bsum;
                    }
                }

                if (amax >= bmax) Console.WriteLine("{0} vs {1} HOST WIN", amax, bmax);
                else Console.WriteLine("{0} vs {1} GUEST WIN", amax, bmax);
            }
        }
    }
}