笔试真题解析2 | 最近刷了一套京东笔试真题,感觉还不错

题目来源:2024年京东春招技术通用岗位第一批笔试

1. 快乐字符串

题目描述

题目链接:快乐字符串

判断一个字符串是否包含以下任意一个连续子串:"cheerful"、"glad"、"happy"、"pleased"。
如果包含,则这个字符串被认为是"快乐的"。

解题思路

这是一个简单的字符串匹配问题,我们可以:

  1. 对每个输入字符串,检查是否包含任意一个目标子串
  2. 使用字符串的find函数或者暴力匹配都可以解决

代码实现

#include <iostream>
#include <string>
using namespace std;

bool isHappy(string& s) {
    string happy_words[] = {"cheerful", "glad", "happy", "pleased"};
    for (const string& word : happy_words) {
        if (s.find(word) != string::npos) {
            return true;
        }
    }
    return false;
}

int main() {
    int T;
    cin >> T;
    while (T--) {
        string s;
        cin >> s;
        cout << (isHappy(s) ? "Yes" : "No") << endl;
    }
    return 0;
}

复杂度分析

  • 时间复杂度:,其中 是输入字符串长度, 是所有快乐词的总长度
  • 空间复杂度:,只使用了常数额外空间

2. 特殊的科学计数法

题目描述

题目链接:特殊的科学计数法

将一个正整数转换为科学计数法形式,其中数值部分需要四舍五入到小数点后一位。

解题思路

  1. 计算数字的位数,确定指数
  2. 提取首位和第二位数字,进行四舍五入处理
  3. 格式化输出结果

代码实现

#include <iostream>
#include <string>
using namespace std;

string to_scientific(string s) {
    int length = s.length();
    
    // 获取第一个数字
    int first = s[0] - '0';
    
    // 获取第二个数字并四舍五入
    int second = 0;
    if (length > 1) {
        second = s[1] - '0';
        if (length > 2 && (s[2] - '0') >= 5) {
            second++;
            if (second == 10) {
                first++;
                second = 0;
                if (first == 10) {
                    first = 1;
                    second = 0;
                    length++; // 位数增加1
                }
            }
        }
    }
    
    return to_string(first) + "." + to_string(second) + "*10^" + to_string(length-1);
}

int main() {
    string n;
    cin >> n;
    cout << to_scientific(n) << endl;
    return 0;
}

复杂度分析

  • 时间复杂度:,其中 是输入的数字
  • 空间复杂度:,用于存储数字的字符串表示

3. 素数对

题目描述

题目链接:素数对

给定一个正整数,找出所有满足以下条件的三元组的个数:

  1. 均为质数

解题思路

  1. 首先使用埃氏筛法筛选出不超过的所有素数
  2. 枚举每个素数,计算其平方
  3. 对于每个,枚举另一个素数,然后计算
  4. 如果也是素数且在范围内,就找到了一组合法解
  5. 优化:
    • 使用静态数组预处理素数,避免动态内存分配
    • 超出范围时可以提前终止内层循环

代码实现

#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
static const int MAX = 500005;
bool isPrime[MAX];

void makePrime() {
    for (int i = 0; i < MAX; i++)
        isPrime[i] = true;

    isPrime[0] = false;
    isPrime[1] = false;

    int n = sqrt(MAX);
    for (int i = 2; i <= n; i++) {
        if (!isPrime[i])
            continue;
        for (int j = i * 2; j < MAX; j += i)
            isPrime[j] = false;
    }
}

int main() {
    int N;
    cin >> N;
    vector<ll> p;
    makePrime();
    for (int i = 2; i <= N; i++) {
        if (isPrime[i])
            p.push_back(i);
    }
    int ans = 0;
    for (int i = 0; i < p.size(); i++) {
        for (int j = 0; j < p.size(); j++) {
            ll t = p[i] * p[i] - p[j];
            if (t < 1 || t > N)
                break;
            if (isPrime[t]) {
                ans++;
            }
        }
    }
    cout << ans << endl;
    return 0;
}

复杂度分析

  • 时间复杂度:,其中是不超过的素数个数。对于每个素数,我们需要枚举所有可能的
  • 空间复杂度:,其中是预定义的最大值500005。主要用于存储素数筛选结果

4. 循环节

题目描述

题目链接:循环节

计算的小数表示中循环节的长度。

解题思路

  1. 模拟长除法的过程
  2. 使用哈希表记录余数出现的位置
  3. 当余数重复出现时,就找到了循环节

代码实现

#include <bits/stdc++.h>
#define rep(x, s, t) for(llint (x) = (s); (x) <= (t); (x)++)
#define chmin(x, y) (x) = min((x), (y))
#define chmax(x, y) (x) = max((x), (y))
#define all(x) (x).begin(),(x).end()
#define inf 1e18

using namespace std;

typedef long long llint;
typedef long long ll;
typedef pair<llint, llint> P;

ll T;
ll n, mod;

llint modpow(llint a, llint n)
{
    if(n == 0) return 1;
    if(n % 2){
        return ((a%mod) * (modpow(a, n-1)%mod)) % mod;
    }
    else{
        return modpow((a*a)%mod, n/2) % mod;
    }
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);

    cin >> T;
    while(T--){
        cin >> n;

        while(n % 5 == 0) n /= 5;
        while(n % 2 == 0) n /= 2;

        if(n == 1){
            cout << 1 << endl;
            continue;
        }

        int res = n, t = n;
        for(int i = 2; i*i <= t; i++){
            if(t % i == 0){
                res = res / i * (i-1);
                for(; t % i == 0; t /= i);
            }
        }
        if(t != 1) res = res / t * (t-1);

        ll ans = inf; mod = n;
        for(llint i = 1; i*i <= n; i++){
            if(res % i == 0){
                if(modpow(10, i) == 1) chmin(ans, i);
                if(modpow(10, res/i) == 1) chmin(ans, res/i);
            }
        }
        cout << ans << endl;
    }

    return 0;
}

复杂度分析

  • 时间复杂度:,最坏情况下需要计算 个余数
  • 空间复杂度:,用于存储余数出现的位置

总结

这四道题目涵盖了字符串处理、数学计算、素数筛选和模拟计算等多个方面,是很好的笔试练习题。其中:

  1. 快乐字符串判定考察基本的字符串匹配能力
  2. 科学计数法转换需要细心处理数值计算和格式化输出
  3. 素数三元组计数综合运用素数筛选和组合计数
  4. 循环小数长度则需要理解除法原理并灵活运用哈希表

欢迎大家到牛客网练习更多类似的题目,提高编程能力!
在实际笔试中,熟练掌握这些基本算法和解题技巧将帮助你在笔试中取得好成绩。

全部评论
接好运
点赞 回复 分享
发布于 03-27 22:07 北京
活捉学长
点赞 回复 分享
发布于 03-28 09:12 广东
代码实现很清晰
点赞 回复 分享
发布于 03-28 12:09 重庆

相关推荐

评论
5
4
分享

创作者周榜

更多
牛客网
牛客企业服务