校园招聘-2017阿里C/C++研发工程师内推笔试编程题

序言

笔试题型:20道单选 + 2道编程

时间:40min + 80min

两道编程题解答如下


字符串字典最少单词匹配


1. 题目描述

给定一个字符串S和有效单词的字典D,请确定可以插入到S中的最小空格数,使得最终的字符串完全由D中的有效单词组成,并输出解。
如果没有解则应该输出n/a

例如
输入
S = “ilikealibaba”
D = [“i”, “like”, “ali”, “liba”, “baba”, “alibaba”]

Example Output:

输出
“i like alibaba”

解释
字符串S可能被字典D这样拆分

“i like ali baba”
“i like alibaba”

很显然,第二个查分结果是空格数最少的解。


2. 要求和示例

编译器版本: gcc 4.8.4
请使用标准输入输出(stdin,stdout) ;请把所有程序写在一个文件里,勿使用已禁用图形、文件、网络、系统相关的头文件和操作,如sys/stat.h , unistd.h , curl/curl.h , process.h

时间限制: 3S (C/C++以外的语言为: 5 S) 内存限制: 128M (C/C++以外的语言为: 640 M)

输入:
第一行为字符串S 第二行为输入一个整数表示字典中字符串的个数 其余行为字典中的内容

输出:
输出为加入空格后的字符串

输入范例:
ilikealibaba 6 i like ali liba baba alibaba

输出范例:
i like alibaba


3. 代码(C)

#include 
#include 
#include 
#include 

#define MAX_DICT_LEN 255
#define MAX_STR 255

typedef struct simple_str
{
    const char * str;
    int len;
    int replaceableFlag;        //是否能在其他字符串中找到完全匹配字段,可以replaceableFlag = 1
}simple_str_t;

void mincut(simple_str_t* str, simple_str_t* dict, int dict_len);
void MatchWithLongerString(simple_str_t* string1, simple_str_t* string2);

int main(int argc, const char * argv[])
{
    char strS[MAX_STR];
    int nDict;
    simple_str_t dict[MAX_DICT_LEN];
    simple_str_t srcStr;

    scanf("%s", strS);
    scanf("%d", &nDict);

    //字符串S初始化
    srcStr.str = strdup(strS);
    srcStr.len = strlen(strS);
    srcStr.replaceableFlag = 0;

    //字典D有效单词初始化
    int i = 0;
    for (; i < nDict; i++)
    {
        scanf("%s", strS);
        dict[i].str = strdup(strS);
        dict[i].len = strlen(strS);
        dict[i].replaceableFlag = 0;
    }

    mincut(&srcStr, dict, nDict);

    return 0;
}

void mincut(simple_str_t* str, simple_str_t* dict, int dict_len)
{
    //每个字符串均与更长字符串进行匹配验证
    int j, cnt;
    for (j = 0; j < dict_len; j++)
    {
        for (cnt = 0; cnt < dict_len; cnt++)
        {
            if (dict[j].len != 1 && dict[j].len < dict[cnt].len)    //长度等于1是不可替换的,像i,而且因为每个单词都是有效单词不用担心出现k,e这种单个字母
                MatchWithLongerString(&dict[j], &dict[cnt]);
        }
    }

    //根据匹配验证结果给出拆分结果
    int k = 0;
    for (; k < dict_len; k++)
    {
        if (dict[k].replaceableFlag != 1)
            printf("%s%c", dict[k].str, k == dict_len - 1 ? '\n' : ' ');
    }
}

/* 匹配验证函数:完全匹配 */
void MatchWithLongerString(simple_str_t* string1, simple_str_t* string2)
{
    char ch = string1->str[0];
    int length1 = string1->len;
    int length2 = string2->len;
    int i = 0, j = 0;
    while (i < length1 && j < length2)
    {
        if (ch != string2->str[j])
        {
            if (i != 0)
                return;
            j++;
            continue;
        }
        else
        {
            i++;
            j++;
            if (i == length1)
            {
                string1->replaceableFlag = 1;       //完全匹配
                return;
            }
            ch = string1->str[i];
        }
    }
}

一些说明:本程序输入输出样例验证正确,但仍存在如下问题

[1] 只考虑了字典内不同单词之间完全匹配的情况,没有考虑部分匹配(而且是结尾字母匹配),如ali,alibaba,babahangzhou,hang,zhou这样的情况

[2] 这种情况下显然是ali, babahangzhou空格数最少,尽管alibaba和babahangzhou不完全匹配,但也不能按照上述程序保留alibaba并直接输出

[3] 需要再添加部分匹配的说明,然后比较分别使用这些部分匹配单词的空格数,取最小的。


诸侯割据,间谍情报


1. 题目描述

中国历史上曾出现过多次诸侯割据的时期,诸侯之间通过各种方式派出间谍来刺探军情,留下了许多惊心动魄的谍战故事,其中有一个是这样的:A国在B国安插了多名间谍,有一次这些间谍刺探到B国将在T时间攻打A国,如果A国不做防备则A国必败;如果A国能提前埋伏则A国必胜,所以A国的间谍需要在T之前将情报安全的送回A国。为了避免情报被B国截获而取消攻打计划:A国的间谍采用了一种特殊的编码算法,会将情报编码在m份数据中,只有同时拿到至少任意的n份数才能解码出情报;这m份数据会由m个间谍分别送出,避免同时被B国捕获。由于输送情报的过程中要躲避B国的随机检查,输送情报的时间是不固定的,A国间谍已经将之前情报的输送时间都记录下来。A国间谍需要估算出A国拿到完整情报时间的期望值。

:为了简单起见,m个间谍都会成功的把各自的情报送回A国;所耗费的时间是独立的。

概念抽象:A国间谍记录的情报输送时间的情况:会记录每个时间总共出现的次数,以Point结构表示:
struct Point
{
int value; // 情报输送时间
int num; // value出现过的次数。
double ratio; // value在所有情报输送占的概率。
};


2. 要求和示例

编译器版本: gcc 4.8.4
请使用标准输入输出(stdin,stdout) ;请把所有程序写在一个文件里,勿使用已禁用图形、文件、网络、系统相关的头文件和操作,如sys/stat.h , unistd.h , curl/curl.h , process.h

时间限制: 3S (C/C++以外的语言为: 5 S) 内存限制: 128M (C/C++以外的语言为: 640 M)

输入:
输入总共分三部分: 1.m n 2.Point个数 3.每个Point中value 和 num的值

输出:
A国拿到完整情报的时间期望值。 以浮点数表示,精确到小数点后6位,不足6位补零。

输入范例:
1 1 1 1 2

输出范例:
1.000000


3. 代码(C)

#include 
#include 
#include 

typedef struct PointStruct
{
    int value;
    int num;
    double ratio;
}Point,*PS;

void Input(PS *points, int n);
double CalculateExpectation(PS *points, int n, int min);

int main()
{
    int total = 0;              //间谍数m
    scanf("%d", &total);
    int min = 0;                //间谍数n
    scanf("%d", &min);

    int pointNum = 0;           //Points个数
    scanf("%d", &pointNum);
    PS points[pointNum];

    Input(points, pointNum);

    double res = CalculateExpectation(points, pointNum, min);
    printf("%06lf", res);       //06可不加,默认保留6位小数

    return 0;
}


void Input(PS *points, int n)
{
    //初始化
    int i;
    for (i = 0; i < n; i++)
    {
        points[i] = (PS)malloc(sizeof(Point));
        memset(points[i], 0, sizeof(Point));
    }
    //赋值
    double sum = 0;
    int j;
    for (j = 0; j < n; j++)
    {
        scanf("%d",&(points[j] ->value));
        scanf("%d", &(points[j] ->num));
        sum = sum + (double)(points[j]->num);
    }
    int k;
    for (k = 0; k < n; k++)
    {
        points[k]->ratio = (double)(points[k]->num) / sum;
    }
}


double CalculateExpectation(PS *points, int n, int min)
{
    int q = 0;
    double ans[min];
    double result = 0;
    while (q < min)
    {
        ans[q] = points[q]->ratio * (double)points[q]->value;
        result += ans[q];
        q++;
    }
    return result;
}


2017.08.26

你可能感兴趣的:(校园招聘)