当前位置:首页 > 题解目录 > 正文内容

【题解】基因锁

亿万年的星光12个月前 (04-11)题解目录862

【题目描述】

小X终于意识到需要花大力气减重了,他询问了若干个减重专家后决定采用最适合年轻人的运动减重方案,考虑再三,小X最终选择了打羽毛球的方式,一个原因是小X的小伙伴大都喜欢打羽毛球,其次是打羽毛球要抬头,对活动颈椎有好处,刚好可以缓冲编程久了对颈椎的压迫。
经过一个月的努力,小X的国际象棋 AI 在机器学习的环境中进步神速,已经能够轻松战胜深蓝了,但小X的体重却没有太大变化,离第一目标 Q 老师尚有一段距离,这天小X跟往常一样白天打羽毛球,晚上训练 AI 后就睡觉了,睡梦中小X梦见自己先是被一束强光罩住了,随后被吸进了 UFO,落到了 UFO 的甲板上,只见一只会说人话的机器狗迎上前来,对小X说:“小X先生好,我家主人在会客舱等你多时了!”
随后小X被带到了一位长了三只眼的外星首领面前。
外星首领很友善地和小X握了手,然后对小X说:“你做的 AI 非常棒,我已经很多年未遇对手了,今天跟你的 AI 打得旗鼓相当,十分过瘾,这次请你来作客是想和你交个朋友,你有什么要求尽管提,我们会尽量满足!”小X听罢受宠若惊,心想外星科技这么发达,也许有办法让我立刻变得像中天学长一样帅!

于是小X提出了这个超高难度的要求,外星首领听后微微一笑:“你这个要求可以满足,但我们要对你的基因进行一次分析,把你基因中的肥胖基因找出来,然后给它们加上锁!象我们熟知的那样,人类的基因序列(英文缩写为 DNA)是一个由字母’A’,‘C’,‘G’,'T’组成的字符串,肥胖基因是其中的一个子串(子串为原串中一段连续的字符),外星人对小X的基因手术过程是这样的:先找出所有的肥胖基因,并将它们用基因墨水染成红色,然后将某些字符加上基因锁,一把基因锁只能锁住一个字符,一个肥胖基因只要有一个字符加上了基因锁,则这个肥胖基因就不再起作用,现在要你计算有多少个字符被基因墨水染成了红色?最少需要多少把基因锁才能将所有的肥胖基因锁住?

【输入描述】

第一行包含两个用空格隔开的正整数 L1,L2,表示小X基因的长度和肥胖基因的长度。
第二行为一个长度为 L1 的字符串,表示小X的基因。
第三行为一个长度为 L2 的字符串,表示肥胖基因。数据保证 L1>L2。

【输出描述】

输出一行包含两个整数,表示被基因墨水染成了红色的字符个数和所需的基因锁数量,两数之间严格用一个空格隔开。

【样例输入】

16 3
CGCGCATCGCATTAGG
CGC

【样例输出】

8 2


【题目分析】

主要解决两个问题:

一是找出所有肥胖基因在小X基因序列中出现的位置,并计算被染成红色(即属于肥胖基因的字符)的字符个数;

二是计算最少需要多少把基因锁,使得每个肥胖基因至少有一个字符被锁住。



具体步骤

  1. 输入处理:读取小X基因的长度 L1、肥胖基因的长度 L2,以及小X的基因序列和肥胖基因序列。

  2. 查找肥胖基因:在小X的基因序列中找出所有肥胖基因的出现位置。

  3. 计算红色字符个数:统计所有肥胖基因覆盖的字符个数,注意避免重复计算。

  4. 计算最少基因锁数量:通过贪心算法,选择合适的字符加锁,使得用最少的锁锁住所有肥胖基因。


【参考答案】

#include <iostream> 
using namespace std; 
 
const int MAX_LEN = 10000; 
 
int main() { 
    int L1, L2; 
    char gene[MAX_LEN], fatGene[MAX_LEN]; 
    bool isRed[MAX_LEN] = {false};  // 标记字符是否被染成红色 
    bool isLocked[MAX_LEN] = {false};  // 标记字符是否被加锁 
 
    // 输入小X基因的长度和肥胖基因的长度 
    cin >> L1 >> L2; 
 
    // 输入小X的基因序列 
    for (int i = 0; i < L1; i++) { 
        cin >> gene[i]; 
    } 
 
    // 输入肥胖基因序列 
    for (int i = 0; i < L2; i++) { 
        cin >> fatGene[i]; 
    } 
 
    // 查找肥胖基因并标记红色字符 
    for (int i = 0; i <= L1 - L2; i++) { 
        bool match = true; 
        for (int j = 0; j < L2; j++) { 
            if (gene[i + j] != fatGene[j]) { 
                match = false; 
                break; 
            } 
        } 
        if (match) { 
            for (int j = 0; j < L2; j++) { 
                isRed[i + j] = true; 
            } 
        } 
    } 
 
    // 计算红色字符个数 
    int redCount = 0; 
    for (int i = 0; i < L1; i++) { 
        if (isRed[i]) { 
            redCount++; 
        } 
    } 
 
    // 计算最少基因锁数量 
    int lockCount = 0; 
    for (int i = 0; i <= L1 - L2; i++) { 
        bool match = true; 
        for (int j = 0; j < L2; j++) { 
            if (gene[i + j] != fatGene[j]) { 
                match = false; 
                break; 
            } 
        } 
        if (match) { 
            bool isCovered = false; 
            for (int j = 0; j < L2; j++) { 
                if (isLocked[i + j]) { 
                    isCovered = true; 
                    break; 
                } 
            } 
            if (!isCovered) { 
                // 选择最后一个字符加锁 
                isLocked[i + L2 - 1] = true; 
                lockCount++; 
            } 
        } 
    } 
 
    // 输出结果 
    cout << redCount << " " << lockCount << endl; 
 
    return 0; 
}


代码解释

输入部分:使用 cin 读取小X基因的长度 L1、肥胖基因的长度 L2,以及小X的基因序列和肥胖基因序列。

查找肥胖基因:通过两层循环遍历小X的基因序列,检查每个长度为 L2 的子串是否与肥胖基因匹配。如果匹配,则将该子串中的所有字符标记为红色。

计算红色字符个数:遍历 isRed 数组,统计标记为红色的字符个数。

计算最少基因锁数量:再次遍历小X的基因序列,查找肥胖基因。对于每个未被加锁覆盖的肥胖基因,选择其最后一个字符加锁,以确保用最少的锁锁住所有肥胖基因。

输出结果:将红色字符个数和最少基因锁数量输出,中间用一个空格隔开


    扫描二维码推送至手机访问。

    版权声明:本文由青少年编程知识记录发布,如需转载请注明出处。

    分享给朋友:

    相关文章

    【题解】约瑟夫问题2

    【题解】约瑟夫问题2

    【题目描述】M个人围成一圈,每分钟相邻的两个人可以交换位置(只能有一对交换)。求使M个人的顺序颠倒(即每个人左边相邻的人换到右边,右边相邻的人换到左边)所需的最少时间(分钟数)。【输入描述】 ...

    【题解】跳格子

    【题目描述】地面上有一排长度为n的格子1-n,每个格子上都有一个数xi,开始时你在位置0,每次你可以向前跳1-2格,然后取走格子上的数,直到跳到位置n+1。取走的数的和就是你的得分,现在你想知道你可能...

    【题解】开花

    【题解】开花

    【题目描述】小A所在的学校又迎来了一年一度的开花活动,有 n 名学生被评为文学优秀奖,m 名学生被评为体育优秀奖。现已知两个奖项获奖同学的编号,每个同学都有唯一的编号。只有同时被评为文学优秀奖和体育优...

    【题解】感应门

    【题目描述】感应门会在有人经过的时候自动打开,冷却d 秒后自动关闭。如果有人在感应门打开的状态下通过,那么冷却时间会重置,重新冷却d秒后再关闭。在一段时间内,有 n个人陆续通过了感应门,他们...

    2020CSPJ-直播获奖

    【题目描述】NOI2130 即将举行。为了增加观赏性,CCF 决定逐一评出每个选手的成绩,并直播即时的获奖分数线。本次竞赛的获奖率为w%,即当前排名前 w% 的选手的最低成绩就是即时的分数线...

    【题解】采摘花生2

    【题目描述】Hello Kitty又一次来到花生地里摘花生,从左上角进入花生地,从右下角出去,只能向右或者向下,请问Hello Kitty应该沿着什么样的路线走,能够摘到的花生数量最多(假设花生地里没...