(更加详细解题思路和CPP、Java代码加我微信获取)
# 第一题:全相等import sysdef is_good_substring(count_arr): """ 判断当前字符计数数组对应的子串是否为好子串 :param count_arr: 长度为26的列表,记录a-z每个字符的出现次数 :return: 是好子串返回True,否则返回False """ base_count = 0 # 基准出现次数,记录第一个出现字符的次数 for num in count_arr: if num > 0: if base_count == 0: base_count = num # 初始化基准次数 elif num != base_count: return False # 存在字符次数不一致,不是好子串 return True # 所有出现字符次数一致,是好子串def calculate_good_substrings(s): """ 计算字符串中好子串的总数量 :param s: 输入的小写字母字符串 :return: 好子串的数量 """ str_len = len(s) result = 0 # 记录好子串总数 # 枚举所有左端点 for left in range(str_len): char_count = [0] * 26 # 每次左端点更新,重新初始化字符计数数组 # 枚举右端点,从左端点开始向右扩展 for right in range(left, str_len): # 计算当前字符对应的数组下标(a->0, b->1, ..., z->25) char_index = ord(s[right]) - ord('a') char_count[char_index] += 1 # 对应字符计数+1 # 判断当前子串是否为好子串,是则结果+1 if is_good_substring(char_count): result += 1 return resultdef main(): """主函数,处理输入输出并调用核心逻辑""" read_input = sys.stdin.readline # 简化输入读取 test_num = int(read_input().strip()) # 读取测试数据组数 res_list = [] # 存储每组测试数据的结果 for _ in range(test_num): n = int(read_input().strip()) # 读取字符串长度 str_s = read_input().strip() # 读取字符串 # 计算当前组的好子串数量并加入结果列表 res_list.append(str(calculate_good_substrings(str_s))) # 输出所有结果,每组结果占一行 sys.stdout.write("\n".join(res_list))if __name__ == "__main__": main()
第二题:文本数值混合特征工程
题目内容
现有一个文本与数值的混合数据,需要你在仅使用numpy/pandas/scikit-learn的前提下,实现下表所示四段式特征工程+双基模型平均流程,并输出测试集标签。
核心流程要求
词级TF-IDF:TfidfVectorizer(lowercase = True, stop_words = "english", ngram_range = (1, 2), sublinear_tf = True)字符3-gram TF-IDF:TfidfVectorizer(analyzer = "char", ngram_range = (3, 3), lowercase = True, sublinear_tf = True)数值特征处理:对输入数值特征做StandardScaler标准化后,每列进行二次多项展开PolynomialFeatures(degree = 2, include_bias = False)特征合并:拼接三个特征矩阵,即hstack(1,2,3)得稀疏矩阵模型A:LogisticRegression(penalty = 'l2', C = 1.0, solver = 'liblinear', max_iter = 1000, random_state=42)模型B:SGDClassifier(loss = 'log_loss', penalty = "l2", alpha = 1e-4, max_iter = 1000, random_state = 42)软投票:将两个模型输出的正类概率结果平均,最终阈值大于0.5则标签为1,否则标签为0输入描述输入为一行JSON格式数据,包含train_txt(训练集文本)、train_num(训练集数值特征)、train_y(训练集标签)、test_txt(测试集文本)、test_num(测试集数值特征)。
输出描述仅一行:[pred_1,pred_2,...,pred_n],长度等于测试集数量的JSON整数数组(0/1),以空格间隔。
补充说明
为确保通过测试用例,仅允许使用numpy/pandas/scikit-learn。测试样例
{"train_txt": ["great food and service", "fantastic taste", "delicious pizza", "awesome restaurant"], "train_num": [[1,2],[3,4],[5,6],[7,8]], "train_y": [1,1,0,0], "test_txt": ["bad food", "good taste"], "test_num": [[2,3],[4,5]]}
[0, 1]
样例说明
输入包含4条训练数据、2条测试数据,经特征工程和双模型平均预测后,测试集第一条标签为0,第二条标签为1,故输出[0, 1]。
解题思路
核心步骤
- 文本特征提取
- 词级 TF-IDF:使用指定参数的
TfidfVectorizer处理文本,提取 1-2 元词特征; - 字符 3-gram TF-IDF:使用字符级分析器,提取 3 元字符特征;
- 数值特征处理
- 标准化:对数值特征用
StandardScaler做 Z-score 标准化; - 二次多项展开:对标准化后的数值特征做 2 次多项式展开(不含偏置项);
- 特征合并:将词级 TF-IDF、字符 3-gram TF-IDF、处理后的数值特征横向拼接为稀疏矩阵;
- 模型训练与预测
- 训练 LogisticRegression 和 SGDClassifier 两个模型;
- 分别输出测试集正类概率,取平均值后按 0.5 阈值生成最终标签。
带详细注释的代码实现(更加详细解题思路和CPP、Java代码加我微信获取)
# 第二题:文本数值混合特征工程import sysfrom ast import literal_evalfrom scipy.sparse import hstack, csr_matrixfrom sklearn.feature_extraction.text import TfidfVectorizerfrom sklearn.preprocessing import StandardScaler, PolynomialFeaturesfrom sklearn.linear_model import LogisticRegression, SGDClassifierdef process_feature_and_predict(data): """ 按要求完成特征工程、模型训练和预测 :param data: 解析后的字典,包含训练和测试的文本、数值、标签数据 :return: 测试集的预测标签列表 """ # 从输入数据中提取训练和测试集的各个部分 train_text = data["train_txt"] train_numeric = data["train_num"] train_label = data["train_y"] test_text = data["test_txt"] test_numeric = data["test_num"] # 1. 构建词级TF-IDF特征 word_tfidf = TfidfVectorizer( lowercase=True, stop_words="english", ngram_range=(1, 2), sublinear_tf=True ) train_word_feat = word_tfidf.fit_transform(train_text) # 训练集拟合并转换 test_word_feat = word_tfidf.transform(test_text) # 测试集仅转换 # 2. 构建字符3-gram TF-IDF特征 char_tfidf = TfidfVectorizer( analyzer="char", ngram_range=(3, 3), lowercase=True, sublinear_tf=True ) train_char_feat = char_tfidf.fit_transform(train_text) # 训练集拟合并转换 test_char_feat = char_tfidf.transform(test_text) # 测试集仅转换 # 3. 处理数值特征:标准化 + 二次多项式展开 scaler = StandardScaler() # 初始化标准化器 poly = PolynomialFeatures(degree=2, include_bias=False) # 初始化多项式展开器 train_num_std = scaler.fit_transform(train_numeric) # 训练集数值特征标准化 test_num_std = scaler.transform(test_numeric) # 测试集数值特征标准化 train_num_poly = poly.fit_transform(train_num_std) # 训练集标准化后多项式展开 test_num_poly = poly.transform(test_num_std) # 测试集标准化后多项式展开 # 将数值特征转为稀疏矩阵,方便与TF-IDF稀疏特征拼接 train_num_sparse = csr_matrix(train_num_poly) test_num_sparse = csr_matrix(test_num_poly) # 4. 特征合并:横向拼接词级、字符级、数值特征 train_total_feat = hstack([train_word_feat, train_char_feat, train_num_sparse]) test_total_feat = hstack([test_word_feat, test_char_feat, test_num_sparse]) # 5. 训练模型A:逻辑回归 model_log = LogisticRegression( penalty="l2", C=1.0, solver="liblinear", max_iter=1000, random_state=42 ) model_log.fit(train_total_feat, train_label) # 6. 训练模型B:随机梯度下降分类器(逻辑损失) model_sgd = SGDClassifier( loss="log_loss", penalty="l2", alpha=1e-4, max_iter=1000, random_state=42 ) model_sgd.fit(train_total_feat, train_label) # 7. 软投票:获取两个模型的正类概率并取平均 prob_log = model_log.predict_proba(test_total_feat)[:, 1] # 模型A正类概率 prob_sgd = model_sgd.predict_proba(test_total_feat)[:, 1] # 模型B正类概率 avg_prob = (prob_log + prob_sgd) / 2.0 # 概率平均值 # 根据阈值0.5生成最终预测标签 predict_label = [1 if p > 0.5 else 0 for p in avg_prob] return predict_labeldef main(): """主函数,处理输入解析和结果输出""" # 读取整行输入并解析为字典 input_str = sys.stdin.read().strip() input_data = literal_eval(input_str) # 调用核心函数得到预测结果 pred_result = process_feature_and_predict(input_data) # 按要求格式输出结果 print("[" + ", ".join(map(str, pred_result)) + "]")if __name__ == "__main__": main()
第三题:四元异或
题目内容
给定一个长度为n的整数数组a1,a2,...,an与整数k,请判断是否存在四个两两不同的下标i,j,p,q(即i,j,p,q互不相同),使得ai XOR aj XOR ap XOR aq = k。若存在输出Yes,否则输出No。
名词解释按位异或(记作XOR):对每一位二进制独立计算,相同为0,不同为1。两两不同:四个下标互不相同,不可复用同一位置的元素。
输入描述每个测试文件均包含多组测试数据。第一行输入一个整数T(1 ≤ T ≤ 1000)代表数据组数,每组测试数据描述如下:
第一行输入两个整数n(4 ≤ n ≤ 1000),k(0 ≤ k ≤ 10^9)。第二行输入n个整数,依次为a1,a2,...,an(0 ≤ ai ≤ 10^9)。所有测试中n的总和≤4000。
输出描述输出T行,若存在满足条件的四元组,输出Yes;否则输出No。
测试样例
34 41 2 3 45 01 2 4 8 164 71 2 3 7
YesNoYes
样例说明
第一组测试数据:取1,2,3,4,有1 XOR 2 XOR 3 XOR 4 = 4,满足条件输出Yes;第二组测试数据:不存在四个两两不同的数使其异或结果为0,输出No;第三组测试数据:取1,2,3,7,有1 XOR 2 XOR 3 XOR 7 = 7,满足条件输出Yes。核心优化思路
利用异或的性质:a XOR b XOR c XOR d = k → a XOR b XOR c = k XOR d。将四元组拆解为前三个数的异或和第四个数与 k 的异或的匹配问题,步骤如下:
- 预处理所有「三元组(i,j,p)的异或值 + 对应的下标集合」,存储到字典中(键:异或值,值:下标集合列表);
- 遍历每个下标 q,计算
target = k XOR a[q]; - 检查字典中是否存在
target对应的三元组下标集合,且该集合与 q 无交集(保证四个下标互不相同);
复杂度分析
- 预处理三元组:O (n³),但 n≤1000 时 n³=10⁹,看似超时,但实际测试中 n 总和≤4000,且大部分用例 n 较小,结合提前终止(找到符合条件的就返回),可以通过;
- 进一步优化:可先枚举二元组(i,j)的异或值,存储
{异或值: [(i,j)]},再枚举(p,q)计算target = k XOR a[p] XOR a[q],检查是否存在 (i,j) 与 (p,q) 无交集,时间复杂度降为 O (n²),更高效。