当前位置: 首页 > news >正文

【笔试强训day16】

目录

第一题:字符串替换

描述

输入:

返回值:

第二题:神奇数

输入描述:

输出描述:

输入

输出

第三题:DNA序列

描述

输入描述:

输出描述:

输入:

输出:

输入:

输出:


第一题:字符串替换

题目链接:字符串替换_牛客题霸_牛客网

描述

请你实现一个简单的字符串替换函数。原串中需要替换的占位符为"%s",请按照参数列表的顺序一一替换占位符。若参数列表的字符数大于占位符个数。则将剩下的参数字符添加到字符串的结尾。

给定一个字符串A,同时给定它的长度n及参数字符数组arg,请返回替换后的字符串。保证参数个数大于等于占位符个数。保证原串由大小写英文字母组成,同时长度小于等于500。

示例1

输入:

"A%sC%sE",  7,  [B,D,F],  3

返回值:

"ABCDEF"

这是一道简单的模拟题。两个指针,一个指针遍历字符串A,一个指针遍历arg。

遍历字符串A,遇到%则判断它的后面一个字符是不是s,如果是的话,就替换成arg中的字符。比如字符串A中 i  位置对应的字符是%,那么在确保 i + 1不越界的情况下去检查 i + 1位置的字符是否为s,如果是的话, 就把arg中对应的字符拿过来替换,然后指针指向arg的下一个位置。最终遍历完字符串A后,如果指向arg中字符的指针还没走到尾,那么继续把arg中剩余的字符加入到答案来。

思想是这么个思想,但最终解题的时候并不会在原字符串上动刀,而是另外开一个string来存储结果。

 

class StringFormat {
public:
    string formatString(string A, int n, vector<char> arg, int m) 
    {
        string ans;
        int j = 0;//指向arg的指针
        for(int i = 0; i < n; i++)
        {
            if(A[i] == '%')
            {
                if(i + 1 < n && A[i + 1] == 's')
                {
                    ans += arg[j++];//替换
                    i++;//i当前指向%,此处++后跳过了%,循环中在++,跳过字符s
                } 
                else 
                {
                    //如果不能替换,则原样保留下来
                    ans += A[i];
                }
            }
            else 
            {
                //不能替换,则原样保留下来
                ans += A[i];
            }
        }    
        //arg可能还有字符剩余
        while(j < m)
        {
            ans += arg[j];
            j++;
        }
        return ans;
    }
};

第二题:神奇数

题目链接:神奇数_牛客笔试题_牛客网

给出一个区间[a, b],计算区间内“神奇数”的个数。
神奇数的定义:存在不同位置的两个数位,组成一个两位数(且不含前导0),且这个两位数为质数。
比如:153,可以使用数字3和数字1组成13,13是质数,满足神奇数。同样153可以找到31和53也为质数,只要找到一个质数即满足神奇数。

输入描述:

输入为两个整数a和b,代表[a, b]区间 (1 ≤ a ≤ b ≤ 10000)。

输出描述:

输出为一个整数,表示区间内满足条件的整数个数

示例1

输入

11 20

输出

6

简单举个例子:14

14本身不是质数,但是14可以组合出41,是质数,所以14是神奇数。通过这个例子,我们应该把14当做一个数字1和一个数字4来看,它们随便组合,无关顺序。

题目中提到,组成的两位数中不能含有前导零,比如02这样就是不符合题意的。

下面分析如何解决这个问题。

        我们把输入的数不当做一个十进制数看,而是拆分成一位一位看。所以第一个问题自然就是如何拆分。比如数字12345,怎么拿到这个数的每一位?反复模10,除10即可。拆分数字引申出来的另一个问题是用什么存储这些单独的一位数,我采用vector来存。

        接下来两层for循环枚举所有排列组合的情况,然后一一判断哪些是质数(素数)即可。

问题又来了——如何判断素数。可以用试除法来判断。比如要判断n是否为素数,就用n来依次除上2到sprt(n)之间的数(包含两头),如果都除不尽,就证明是素数;反之,则不是。

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

//判断一个数是否是素数
bool isPrime(int n)
{
    for(int i = 2; i <= sqrt(n); i++)
    {
        if(n % i == 0)
            return false;
    }
    return true;
}
//判断一个数是否是神奇数
int check(int n)
{
    vector<int> arr;
    //拆分数字放到数组中
    while (n) 
    {
        arr.push_back(n % 10);
        n /= 10;
    }
    //枚举所有排列组合情况
    for(int i = 0; i < arr.size(); i++)//枚举十位数
    {
        for(int j = 0; j < arr.size(); j++)//枚举个位数
        {
            //枚举时不能同时枚举同一个位置(重复使用同一位置)
            //不能含有前导零
            if(i != j && arr[i] != 0)
            {
                if(isPrime(arr[i] * 10 + arr[j]))
                    return 1;
            }
        }
    }
    return 0;
}
int main() 
{
    int a, b;
    cin >> a >> b;

    int ans = 0;
    for(int i = a; i <= b; i++)
    {
        //如果是神奇数则返回1,否则返回0
        ans += check(i);
    }
    cout << ans << endl;
    return 0;
}

第三题:DNA序列

题目链接:DNA序列_牛客题霸_牛客网

描述

一个 DNA 序列由 A/C/G/T 四个字母的排列组合组成。 G 和 C 的比例(定义为 GC-Ratio )是序列中 G 和 C 两个字母的总的出现次数除以总的字母数目(也就是序列长度)。在基因工程中,这个比例非常重要。因为高的 GC-Ratio 可能是基因的起始点。

给定一个很长的 DNA 序列,以及限定的子串长度 N ,请帮助研究人员在给出的 DNA 序列中从左往右找出 GC-Ratio 最高且长度为 N 的第一个子串。

DNA序列为 ACGT 的子串有: ACG , CG , CGT 等等,但是没有 AGT , CT 等等

数据范围:字符串长度满足 1≤𝑛≤1000 1≤n≤1000  ,输入的字符串只包含 A/C/G/T 字母

输入描述:

输入一个string型基因序列,和int型子串的长度

输出描述:

找出GC比例最高的子串,如果有多个则输出第一个的子串

示例1

输入:

ACGT
2

输出:

CG

说明:

ACGT长度为2的子串有AC,CG,GT3个,其中AC和GT2个的GC-Ratio都为0.5,CG为1,故输出CG   

示例2

输入:

AACTGTGCACGACCTGA
5

输出:

GCACG

说明:

虽然CGACC的GC-Ratio也是最高,但它是从左往右找到的GC-Ratio最高的第2个子串,所以只能输出GCACG。 

固定长度的滑动窗口问题。

 滑动窗口问题一般都是以下几个步骤:

1)进窗口

2)判断

3)出窗口

4)更新

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

int main() 
{
    string s;
    int N;//窗口长度
    cin >> s >> N;

    int left = 0, right = 0, begin = 0;//需要记录答案的起始下标begin
    int count = 0, maxCount = 0;//count表示当前窗口内C和G的数量,maxCount表示当前C和G的最大数量
    //很固定的滑动窗口写法
    int n = s.size();
    while(right < n)
    {
        if(s[right] == 'C' || s[right] == 'G')//进窗口+判断
            count++;
        while(right - left + 1 > N)//出窗口
        {
            //如果C或G被挤出窗口,那么需要维护count
            if(s[left] == 'C' || s[left] == 'G')
                count--;
            left++;
        }
        if(right - left + 1 == N)//更新结果
        {
            if(count > maxCount)
            {
                maxCount = count;
                begin = left;
            }
        }
        right++;
    }
    //截取答案并输出
    cout << s.substr(begin, N) << endl;
    return 0;
}

 

 

相关文章:

  • go 数据理解
  • 深入剖析 Kafka 的零拷贝原理:从操作系统到 Java 实践
  • 潇洒浪: Dify 上传自定义文件去除内容校验 File validation failed for file: re.json
  • MCU屏和RGB屏
  • 【Linux】Orin NX编译 linux 内核及内核模块
  • Linux内核分页——线性地址结构
  • PharmMapper: 基于配体药效团的在线“反向钓靶”工具
  • AlmaLinux9.5 修改为静态IP地址
  • 深度学习总结(7)
  • 无损分区管理,硬盘管理的“瑞士军刀”!
  • 快速把广告账户绑定到tiktok小店
  • python:将白色背景的png转化为透明背景的png并改变尺寸
  • 【OpenCV 轮廓检测与轮廓筛选】
  • 24V效率高达 94%的同步DCDC转换器WD5030E
  • VBA即用型代码手册:文档Document
  • 《分布式软总线牵手云服务,拓展应用新维度》
  • 新一代AI低代码MES,助力企业数字化升级
  • Redis下载稳定版本5.0.4
  • MySQL学习笔记7【InnoDB】
  • 知识了解02——了解pnpm+vite+turbo+monorepo的完整构建步骤(react子项目)
  • 门户网站开发招标/推广和竞价代运营
  • 静态网站的设计方案/厨师培训
  • 付费小说网站建设/百度ai助手入口
  • 金坛市常州网络推广/江西seo
  • 成都 网站改版/海外推广代理公司
  • 为什么要立刻做网站/广州网络营销