自学内容网 自学内容网

【c++笔试强训】(第二十四篇)

目录

神奇数(数学)

题目解析

讲解算法原理

编写代码

DNA序列(滑动窗⼝)

题目解析

讲解算法原理

编写代码


神奇数(数学)

题目解析

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

2.题目描述

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

输入描述:

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

输出描述:

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

示例1

输入

11 20

输出

6

讲解算法原理

解法:
算法思路:

根据题意模拟就好了,注意⼀些细节问题,⽐如不要出现前导0。

编写代码

c++算法代码:

#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
int a, b;
bool isprim(int n) // 判断是否是质数
{
 if(n < 2) return false;
 for(int i = 2; i <= sqrt(n); i++) // 试除法 {
 if(n % i == 0) return false;
 }
 return true;
}
int check(int n) // 判断是否是神奇数
{
 vector<int> num; while(n)
 {
 num.push_back(n % 10); n /= 10;
 }
 for(int i = 0; i < num.size(); i++) // 枚举⼗位数 {
 for(int j = 0; j < num.size(); j++) // 枚举个位数 {
 if(i != j && num[i] != 0)
 {
 if(isprim(num[i] * 10 + num[j]))
 {
 return 1;
 }
 }
 }
 }
 return 0;
}
int main()
{
 cin >> a >> b;
 int ret = 0;
 for(int i = max(a, 10); i <= b; i++)
 {
 ret += check(i);
 }
 cout << ret << endl;
 return 0;
}

java算法代码:

import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main
{
 public static boolean isprim(int x) // 判断是否是质数 {
 if(x < 2) return false;
 for(int i = 2; i <= Math.sqrt(x); i++) // 试除法 {
 if(x % i == 0) return false;
 }
 return true;
 }
 public static int check(int x) // 判断是否是神奇数 {
 int[] num = new int[10]; int n = 0; while(x != 0)
 {
 num[n++] = x % 10; x /= 10;
 }
 for(int i = 0; i < n; i++) // 枚举⼗位数 {
 for(int j = 0; j < n; j++) // 枚举个位数 {
 if(num[i] != 0 && i != j)
 {
 if(isprim(num[i] * 10 + num[j]))
 { return 1; } } }
 }
 return 0;
 }
 public static void main(String[] args) 
 {
 Scanner in = new Scanner(System.in); int a = in.nextInt(), b = in.nextInt();
 int ret = 0;
 for(int i = Math.max(a, 10); i <= b; i++)
 {
 ret += check(i);
 }
 System.out.println(ret);
 }
}

DNA序列(滑动窗⼝)

题目解析

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

2.题目描述

描述

一个 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 \le n \le 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。    

讲解算法原理

解法:
算法思路:

⻓度固定的滑动窗⼝。

编写代码

c++算法代码:

#include <iostream>
#include <string>
using namespace std;
string s;
int x;
int main()
{
 cin >> s >> x;
 int begin = -1; // 标记结果的起始位置
 int maxCount = 0; // 存储之前的窗⼝⾥⾯ C + G 的个数
 int count = 0; // 统计窗⼝内 C + G
 int left = 0, right = 0, n = s.size();
 while(right < n)
 {
 if(s[right] == 'C' || s[right] == 'G') count++; while(right - left + 1 > x)
 {
 if(s[left] == 'C' || s[left] == 'G') count--; left++;
 }
 if(right - left + 1 == x)
 {
 if(count > maxCount)
 {
 begin = left; maxCount = count; }
 }
 right++;
 }
 cout << s.substr(begin, x) << endl;
 return 0;
}

java算法代码:

import java.util.Scanner;
// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main
{
 public static void main(String[] args) 
 {
 Scanner in = new Scanner(System.in); char[] s = in.next().toCharArray(); int x = in.nextInt();
 int begin = 0; // 标记结果的起始位置
 int maxCount = 0; // 统计以前窗⼝内 C + G 的最⼤值 int left = 0, right = 0, n = s.length;
 int count = 0; // 统计窗⼝内 C + G  while(right < n) {
 if(s[right] == 'C' || s[right] == 'G') count++;
 while(right - left + 1 > x)
 {
 if(s[left] == 'C' || s[left] == 'G') count--; left++;
 }
 if(right - left + 1 == x)
 {
 if(count > maxCount)
 {
 begin = left; maxCount = count; }
 }
 right++;
 }
 for(int i = begin; i < begin + x; i++)
 {
 System.out.print(s[i]);
 }
 }
}


原文地址:https://blog.csdn.net/weixin_73861555/article/details/144077347

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!