柠檬微趣笔试题

题目描述

第一题
题目:求和方式
给定一个正整数 s 和 n 个正整数 , 求有多少种组合的和为 s ?数值相同的两个数视为不同的两个数。

输入描述
第一行两个整数 n,s,含义如题所述;

第二行 n 个整数。

1<=n<=30, 1<=s<=900, 1<=wi<=s

输出描述
输出一个整数表示答案。特别地,如果没有合法方案,输出0。

样例输入
10 5

1 1 1 1 1 1 1 1 1 1

样例输出
252

说明
C(10, 5) = 252

作者:林小白zii
链接:https://www.nowcoder.com/discuss/595750586285395968?anchorPoint=problem
来源:牛客网

#include <iostream>
#include <vector>
#include <map>
using namespace std;

int num_elements, target_sum;
vector<int> elements;
map<pair<int, int>, int> memo;

int countSubsets(int index, int current_sum) {
    // 检查结果是否已经存在于备忘录中
    map<pair<int, int>, int>::iterator it = memo.find(make_pair(index, current_sum));
    if (it != memo.end()) {
        return it->second;
    }
    
    if (index >= num_elements || current_sum > target_sum) {
        return (current_sum == target_sum) ? 1 : 0; // 如果 current_sum 等于 target_sum,则返回 1,否则返回 0
    }
    
    // 递归调用:排除当前元素或包含它
    int result = countSubsets(index + 1, current_sum) + countSubsets(index + 1, current_sum + elements[index]);
    memo[make_pair(index, current_sum)] = result; // 在返回前将结果保存到备忘录中
    return result;
}

int main() {
    cin >> num_elements >> target_sum;
    elements.resize(num_elements);
    for (int i = 0; i < num_elements; ++i) {
        cin >> elements[i];
    }
    
    cout << countSubsets(0, 0) << endl;
    return 0;
}




第二题
题目:Regular Expresssion
实现简单的正则表达式匹配,本题中模式字符串所包含的字符的范围为字母、“.”、“*”、“?"、其中:

“.” 匹配任何单个字符;
“*” 与模式字符串前一个字符组成一组,匹配零个或多个前面的字符;
“?” 与模式字符串前一个字符组成一组,匹配一个或多个前面的字符;
匹配应该覆盖到整个输入的字符串(而不是局部的),测试用例中不会出现超出匹配字符范围之外的字符,也不会出现非法的模式字符串。使用语言提供的正则表达式库将算作无效答案。

输入描述
输入的第一行为需要检测匹配的用例数,接下来的每一行包括两个字符串,前一个字符串为待匹配的字符串,后一个字符串为模式字符串,

待匹配字符串的长度不超过10。

输出描述
对于每一个测试用例,如果匹配则输出一行true,如果不匹配则输出一行false。

样例输入一
3

aa a

aa aa

aaa aa

样例输出一
false

true

false

样例输入二
5

a a.

a a.*

ab .*

ab .?

b a?

样例输出二
false

true

true

true

false

#include <iostream>
#include <vector>
#include <string>

using namespace std;

bool isMatch(string s, string p) {
    int m = s.size();
    int n = p.size();
    
    // dp[i][j] 表示 s 的前 i 个字符和 p 的前 j 个字符是否匹配
    vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));
    
    dp[0][0] = true; // 空字符串匹配空模式
    
    // 初始化 dp[0][j]
    for (int j = 1; j <= n; ++j) {
        if (p[j - 1] == '*') {
            dp[0][j] = dp[0][j - 2];
        }
    }
    
    // 填充 dp 数组
    for (int i = 1; i <= m; ++i) {
        for (int j = 1; j <= n; ++j) {
            if (p[j - 1] == '*') {
                dp[i][j] = dp[i][j - 2]; // * 匹配零次
                if (s[i - 1] == p[j - 2] || p[j - 2] == '.') {
                    dp[i][j] = dp[i][j] || dp[i - 1][j]; // * 匹配多次
                }
            } else if (p[j - 1] == '?' || s[i - 1] == p[j - 1]) {
                dp[i][j] = dp[i - 1][j - 1];
            }
        }
    }
    
    return dp[m][n];
}

int main() {
    // 示例用法
    string s = "aab";
    string p = "c*a*b";
    
    if (isMatch(s, p)) {
        cout << "true" << endl;
    } else {
        cout << "false" << endl;
    }
    
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值