阿里巴巴笔试题

博客园链接 https://www.cnblogs.com/hustyan/p/12531879.html
阿里的笔试真的有点难,两道笔试题一个小时,感觉只能做出一道题来,笔试的时候也没做出来,结束了之后理清思路花了一小时才写好

1. 一副扑克牌,总共有 A 2 3 4 5 6 7 8 9 10 每张牌各4张,从中抽取任意张牌,牌可以有四种出法

1. 单张牌,比如说 A
2. 一对牌,比如说 两个2
3. 五张牌顺子,比如说 A 2 3 4 5
4. 六张牌连对,比如说 A A 2 2 3 3

现在输入是10种牌每张牌的个数,如 1 1 1 2 2 2 2 2 1 1 ,指的是这10张牌每张的个数,现在问最少出几次能把牌出完。

此时的解答是3次,出3个顺子可以达到目标。

深度优先加回溯

#include <iostream>
#include <vector>

using namespace std;

int find6(vector<int> datas, int start, int& loc)
{
    if (start >= 8)
        return 0;
    int min = 10;
    int times = 0;
    for (int i = start; i < 10; i++)
    {
        if (datas[i] < min)    min = datas[i];
        if (min < 2)
        {
            min = 10;
            times = 0;
        }
        else
        {
            times++;
            if (times == 3)
            {
                loc = i - 2;
                if (min == 4)
                    return 2;
                else
                    return 1;
            }
        }
    }
    return 0;
}
void sub6(vector<int>& datas, int loc, int times)
{
    datas[loc] -= 2 * times;
    datas[loc + 1] -= 2 * times;
    datas[loc + 2] -= 2 * times;
}

void add6(vector<int>& datas, int loc) {
    datas[loc] += 2;
    datas[loc + 1] += 2;
    datas[loc + 2] += 2;
}

int find5(vector<int> datas, int start, int& loc)
{
    if (start >= 6)
        return 0;
    int min = 10;
    int times = 0;
    for (int i = start; i < 10; i++)
    {
        if (datas[i] < min)    min = datas[i];
        if (min == 0)
        {
            min = 10;
            times = 0;
        }
        else
        {
            times++;
            if (times == 5)
            {
                loc = i - 4;
                return min;
            }
        }
    }
    return 0;
}
void sub5(vector<int>& datas, int loc, int times)
{
    datas[loc] -= times;
    datas[loc + 1] -= times;
    datas[loc + 2] -= times;
    datas[loc + 3] -= times;
    datas[loc + 4] -= times;
}

void add5(vector<int>& datas, int loc) {
    datas[loc] += 1;
    datas[loc + 1] += 1;
    datas[loc + 2] += 1;
    datas[loc + 3] += 1;
    datas[loc + 4] += 1;
}

void dfs(vector<int>& datas, int& min, int cur, int step, int start)
{
    int loc = 0;
    if (step == 0)
    {
        if (start >= 8)
        {
            dfs(datas, min, cur, 1, 0);
        }
        else
        {
            int nums = find6(datas, start, loc); //loc 是指的找到了并开始的地方
            if (nums == 0)
            {
                dfs(datas, min, cur, 1, 0);
            }
            else
            {
                int n = nums;
                sub6(datas, loc, nums);
                while (n)
                {
                    dfs(datas, min, cur + n, 0, loc + 1);
                    add6(datas, loc);
                    n--;
                }
                dfs(datas, min, cur, 0, loc + 3);
            }
        }
    }
    else if (step == 1)
    {
        if (start >= 6)
        {
            dfs(datas, min, cur, 2, 0);
        }
        else
        {
            int nums = find5(datas, start, loc); //loc 是指的找到了并开始的地方

            if (nums == 0)
            {
                dfs(datas, min, cur, 2, 0);
            }
            else
            {
                int n = nums;
                sub5(datas, loc, nums);
                while (n)
                {
                    dfs(datas, min, cur + n, 1, loc + 1);
                    add5(datas, loc);
                    n--;
                }
                dfs(datas, min, cur, 1, loc + 5);
            }
        }
    }
    else
    {
        int nums = 0;
        for (int i = 0; i < 10; i++)
        {
            if (datas[i] > 0 && datas[i] <= 2)
            {
                nums++;
            }
            else if (datas[i] > 2 && datas[i] <= 4)
            {
                nums += 2;
            }
        }
        cur += nums;
        if (min > cur)
            min = cur;
    }
}

int main()
{
    vector<int>  datas(10);
    for (int i = 0; i < 10; i++)
    {
        cin >> datas[i];
    }
    int min = 50;
    dfs(datas, min, 0, 0, 0);
    cout << min;
}
#阿里巴巴##笔试题目#
全部评论
https://www.nowcoder.com/discuss/388264, 没有参加笔试……看了一下讨论区,不知道题目理解的对不对,按照如下理解写了一段代码= =求指导。 理解的题目:只有a-z这26个字母组成的字符串集合,每个只能最多用1次,求能组成的最长的字母序非递减串。
1 回复 分享
发布于 2020-03-21 20:04
具体的思路就是: 1.  总共有三个状态step,检测连对、检测顺子、统计余下单张和一对的个数 2. 检测连对: 从开始位置start检测(find6),如果检测不到连对就进入下一阶段检测顺子,如果检测到连对,需要判断检测点loc有几个连对(A:4   2:4   3:4  这种就算两个连对),可能有1个连对或者两个连对,这时可能的出牌形式是两个连对、一个连对、零个连对这几种情况,出完之后转到检测点的下一个(loc+1)继续检测对子。 2. 检测顺子:和检测连对一样,也是需要判断检测到的检测点处到底有几个顺子,对应的最多有4个(2:4 3:4  4:4 5:4 6:4 这种就是4个顺子),所以可能的出牌形式是四三二一零个顺子这五种情况,当然也与检测到的个数有关。如果从开始位置(start)检测不到顺子,就跳转到第三个状态。 3. 统计余下单张和一对的个数,这个比较容易想到。
1 回复 分享
发布于 2020-03-20 20:51
A-9不是9种情况吗?老哥你是不是写错了
点赞 回复 分享
发布于 2020-03-21 15:59
请问,顺子只能是按照他规定的5张吗? 大于五张可以吗? 连队也是大于3连行吗?
点赞 回复 分享
发布于 2020-03-20 21:44
这是是所有技术岗都是一样的题目吗
点赞 回复 分享
发布于 2020-03-20 19:19

相关推荐

lllllkin:感觉可以精简到一页简历,有些排版感觉不是必须的。 时间线越早的,你自己越熟悉的放前面。描述可以更精简些,一些问题解决感觉可以不用写具体技术栈,卖个关子,等面试官问。
点赞 评论 收藏
分享
评论
7
26
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务