笔试题型:20道单选 + 2道编程
时间:40min + 80min
两道编程题解答如下
给定一个字符串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”很显然,第二个查分结果是空格数最少的解。
编译器版本: 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
#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] 需要再添加部分匹配的说明,然后比较分别使用这些部分匹配单词的空格数,取最小的。
中国历史上曾出现过多次诸侯割据的时期,诸侯之间通过各种方式派出间谍来刺探军情,留下了许多惊心动魄的谍战故事,其中有一个是这样的: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在所有情报输送占的概率。
};
编译器版本: 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
#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