华为下午编程大赛题目(C/C++) 2012

1.扑克问题
问题描述:
在扑克中,牌的类型包括:A(1),2,3,4,5,6,7,8,9,T(10),J(11),Q(12),K(13),D(小鬼devilkin),B(大鬼Belial)。
请做一个简单的程序,输入两张牌的字符,比如"2"和"K",判断牌的大小,规则如下:
B>D>2>A>K>Q>J>10....>3 最小的为3
判断规则:比较cFirstCard和cSecondCard,如果FirstCar大,那么返回1;如果相同,返回0;如果FirstCar小,返回-1。
要求实现函数:
int CompareOneCard(char cFirstCard, char cSecondCard)

【输入】 char cFirstCard:需要比较的第一张牌
char cSecondCard: 需要比较的第二张牌
注意:输入的为字符’A’,’2’,…,’9’,’T’,’J’,’Q’,’K’,’D’,’B’
【返回】  int类型:返回两张牌的比较结果
注意:不用考虑输入的合法性,这个由函数的使用者保证。输入的牌均为字符’1’,’2’…’9’,大写的’A’,’T’,’J’,’Q’,’K’,’D’,’B’。
举例:  
输入:’4’、’5’,返回:-1
输入:’6’、’6’,返回:0
2. 干瞪眼(30分)
问题描述:
在成都,流行一种扑克游戏叫“干瞪眼”。使用扑克牌,包括:A(1),2,3,4,5,6,7,8,9,T(10),J(11),Q(12),K(13)。
注意:10用T替换,这里暂时不考虑大鬼和小鬼。
两手牌的大小规则如下:
a)    单牌:4比3大,5比4大,只有两张牌刚好大一点时才能进行比较,比较顺序为:A>K>Q>J>T>9>8>7>6>5>4>3。
比如:6大于5,但是不能比4大,6和4不能比较。单牌2属于特殊牌,他可以和其他所有普通单牌比较,并且是最大的。
请注意3,他不能大于任何牌。
b)    对子:即两张牌的点数相同,规则和单牌相似,也需要进行类似处理。两个2是特殊对子,可以大于所有的其他对子。
注意:对子和单牌是不能进行比较的。
c)    炸弹:3个点数相同的牌。炸弹可以大于任何单张和对子,炸弹之间的比较不用像单牌和对子那样,只能大一点才能比较。
只要满足:222>AAA>KKK>QQQ>JJJ>TTT>…>333的规则的即可。即222是最大的,AAA可以大于KKK,也可以大于333。
d)    其他规则暂不考虑实现
现在请你实现一个程序,自动判断两手牌的大小,注意:输入的牌只会出现3种类型:单张,对子,炸弹。张数最多3张。
不会出现2个单牌。比如”25”,也不会出现一个对子加单牌,比如”334”等,类似输入异常你可以不用考虑。
但是pFirstCards为单牌,pSecondCards为对子,类似的组合输入是合法的。
要求实现函数:
int CompareCards(char *pFirstCards, char *pSecondCards)
【输入】  char *pFirstCards:需要比较的第一手牌
char *pSecondCards:需要比较的第二手牌
【返回】  int 类型,返回值说明:
如果pFirstCards和 pSecondCards无法比较,比如”3”和”6”;”55”和”6”等,返回0。
如果pFirstCards大于pSecondCards,返回1。
如果pFirstCards等于 pSecondCards,返回2。
如果pFirstCards小于 pSecondCards,返回3。
注意:不用考虑输入的合法性,这个由函数的使用者保证。输入的牌均为字符’1’,’2’..’9’,大写的’A’,’T’,’J’,’Q’,’K’。
示例
输入: “77”、 “33”,返回:0
输入: “77”、 “77”,返回:2

3. 麻将胡牌(40分)
问题描述:
说起麻将,那可是川渝市民的最爱,无论亲朋好友聚会,还是业务谈判,总是少不了麻将的声音。
现实生活如此,网络上各种各样的麻将游戏也非常的多,现在游戏公司H正在做一款麻将游戏,
其中判断是否胡牌的部分希望由你来做。
成都麻将规则如下:
麻将只能包括3种类型:条,筒,万。没有“门、东南西北、红中”。每种牌都是数字从1到9,每个数字有4张,共36张,筒,万,条均一样。
胡牌规则如下:
a)         手里面的牌最多只有两种类型,即必须打缺一种,不能出现:条,筒,万都存在的情况。
b)         必须有一个对子,即两张相同的牌,比如:两个2筒,两个4条等。
c)         剩余的牌,每3张需要凑成一个有效牌,比如:3个一样的牌(3个2筒),或者3个顺子(1条2条3条),
如果所有的牌都能够凑好,再满足规则b和a,有一个对子,并且所有的牌只有两种,那么就可以胡牌了。
d)         有一种特殊牌,叫做七对,即全部的牌都是成对出现,比如:2筒2筒5筒5筒3筒3筒4条4条8条8条1条1条2条2条,
一共7对,再满足条件a,也可以胡牌。
e)         假设牌不会出现碰的情况,即手里面的牌肯定是14张。输入数据肯定都是麻将牌,不用考虑异常输入。
也不用考虑会输入“门”,“红中”等成都麻将中不会出现的牌。
要求实现函数:
bool IsMahjonggWin(char *pCards)
【输入】  char *pCards:参数说明:
        假设:
条子为:T,2条输入为:2T
筒子为:D,3筒输入为:3D
万子为:W,4万输入为:4W
pCards:输入麻将序列。比如:”1T2T2T2T3T7T8T9T5D4D7D8D8D8D”
【返回】 bool类型:如果能够胡牌,返回true;如果不能胡牌,返回false。
比如:“7T1T8T2T2T2T3T9T5D4D3D8D8D8D”可以转换成“1T2T3T2T2T 7T8T9T3D4D5D8D8D8D”,可以胡牌。
注意:不用考虑输入的合法性,这个由函数的使用者保证。输入的牌为字符串,字母为大写的”TDW”,请编码的时候注意。
示例
输入: “1D2D2D2D3D3D4D4D5D5D5D6D6D7D”,返回:true
输入: “1D1D1D3D3D3D5D5D5D7D7D7D2W3W”,返回false

static int vtable[128] = {
//  0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 0
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 2
    0,12,13, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, // 3
    0,12,15, 0,14, 0, 0, 0, 0, 0, 9,11, 0, 0, 0, 0, // 4
    0,10, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 5
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 7
};

// 问题1:
int CompareOneCard(char cFirstCard, char cSecondCard)
{
    int a = vtable[cFirstCard];
    int b = vtable[cSecondCard];
    
    return a > b ? 1 : ( a < b ? -1 : 0);
}

// 问题2:
int CompareCards(char *pFirstCards, char *pSecondCards)
{
    int n1 = strlen(pFirstCards);
    int n2 = strlen(pSecondCards);

    // Can't compare
    if (n1 < 3 && n2 < 3 && n2 != n1)
    {
        return 0;
    }

    if (n1 > n2)
    {
        return 1;
    }

    if (n1 < n2)
    {
        return 3;
    }

    int a = vtable[*pFirstCards];
    int b = vtable[*pSecondCards];

    if (n1 == 3)
    {
        return a > b ? 1 : ( a < b ? 3 : 2);
    }
    else
    {
        if (abs(a - b) > 1 && a != 13 && b != 13)
        {
            return 0;
        }
        else
        {
            return a > b ? 1 : ( a < b ? 3 : 2);
        }
    }

    return 0;
}

bool CheckMahjongg(int * table, int & c2, int &c3)
{
    int pos = 0;
    while (table[9] > 0)
    {
        if (pos >= 9)
        {
            pos = 0;
        }

        if (table[pos] == 0)
        {
            pos++;
            continue;
        }
        
        if (pos < 7 && table[pos] == 2 && table[pos + 1] < 2)
        {
            c2++;
            table[pos] -= 2;
            table[9] -= 2;
            continue;
        }

        if (pos < 7 && table[pos + 1] > 0 && table[pos + 2] > 0)
        {
            c3++;
            table[pos]--;
            table[pos + 1]--;
            table[pos + 2]--;
            table[9] -= 3;
            continue;
        }

        if (table[pos] == 4)
        {
            c2 += 2;
            table[pos] -= 4;
            table[9] -= 4;
        }
        else if (table[pos] == 3)
        {
            c3++;
            table[pos] -= 3;
            table[9] -= 3;
        }
        else if (table[pos] == 2)
        {
            c2++;
            table[pos] -= 2;
            table[9] -= 2;
        }
        else if (table[pos] == 1)
        {
            return false;
        }
    }
    return true;
}

// 问题3:
bool IsMahjonggWin(char *pCards)
{
    int tableT[10] = {0};
    int tableD[10] = {0};
    int tableW[10] = {0};

    int flag = 0;
    char * pTmp = pCards;
    for (int i = 0; i < 14; i++)
    {
        char s = *pTmp++;
        switch (*pTmp++)
        {
        case 'T':
            {
                flag |= 1;
                tableT[9]++;
                tableT[s-'1']++;
            }
            break;
        case 'D':
            {
                flag |= 2;
                tableD[9]++;
                tableD[s-'1']++;
            }
            break;
        case 'W':
            {
                flag |= 4;
                tableW[9]++;
                tableW[s-'1']++;
            }
            break;
        default:
            break;
        }
    }

    if (flag == 7)
    {
        return false;
    }

    int c2 = 0;
    int c3 = 0;
    bool bret = true;
    bret = bret && CheckMahjongg(tableT, c2, c3);
    bret = bret && CheckMahjongg(tableD, c2, c3);
    bret = bret && CheckMahjongg(tableW, c2, c3);
    if (!bret)
    {
        return false;
    }

    if (c2 != 7 && c2 != 1)
    {
        return false;
    }

    return true;
}


第三题:
#include <iostream>
using namespace std;

bool checkMahjong(char cards[], char count) {
    // 检测完毕,和牌
    if (count == 0) return true;
    // 找到要检测的第一张牌
    int current = 0;
    while (!cards[current]) current++;
    // 判断是否已提取过一对,并尝试提取
    if (count % 3 == 2 && cards[current] >= 2) {
        cards[current] -= 2;
        if (checkMahjong(cards, count - 2)) return true;
        cards[current] += 2;
    }
    // 尝试提取三个相同的牌
    if (cards[current] >= 3) {
        cards[current] -= 3;
        if (checkMahjong(cards, count - 3)) return true;
        cards[current] += 3;
    }
    // 尝试提取顺子
    if (cards[current] >= 1 && cards[current + 1] >= 1 && cards[current + 2] >= 1) {
        cards[current] -= 1; cards[current + 1] -= 1; cards[current + 2] -= 1;
        if (checkMahjong(cards, count - 3)) return true;
        cards[current] += 1; cards[current + 1] += 1; cards[current + 2] += 1;
    }
    return false;
}

bool IsMahjonggWin(char *pCards) {
    // 初始化数据结构。每种类型的牌用一个0分割,这样判断顺子时就能无差别对待
    char cards[29] = {0};
    char cardtable[128] = {0}; cardtable['D'] = 10; cardtable['W'] = 20;
    while (*pCards) {
        cards[*pCards - '0' + cardtable[*(pCards + 1)]]++;
        pCards += 2;
    }
    // 判断是否缺门。依据:统计缺门的数量
    int i, j, count = 0;
    for (i = 0; i < 29; i += 10) {
        for (j = i; j < i + 9; j++) {
            if (cards[j]) break;
        }
        if (j == i + 9) count++;
    }
    if (count == 0) return false;
    // 判断是否七对。依据:数组中的值全为0、2、4
    for (i = 0; i < 29; i++) {
        if (cards[i] != 0 && cards[i] != 2 && cards[i] != 4) break;
    }
    if (i == 29) return true;
    // 递归进行常规牌型判断
    return checkMahjong(cards, 14);
}

int main(int argc, char* argv[])
{
    cout << "Expected = 1: 1D2D2D2D3D3D4D4D5D5D5D6D6D7D = " << IsMahjonggWin("1D2D2D2D3D3D4D4D5D5D5D6D6D7D") << endl;
    cout << "Expected = 0: 1D1D1D3D3D3D5D5D5D7D7D7D2W3W = " << IsMahjonggWin("1D1D1D3D3D3D5D5D5D7D7D7D2W3W") << endl;
    cout << "Expected = 1: 1T1T2T2T6T6T8T8T9T9T1D1D4D4D = " << IsMahjonggWin("1T1T2T2T6T6T8T8T9T9T1D1D4D4D") << endl;
    cout << "Expected = 0: 1T1T2T2T6T6T8T8T9T9T1D1D4W4W = " << IsMahjonggWin("1T1T2T2T6T6T8T8T9T9T1D1D4W4W") << endl;
    getchar();
    return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值