观前提醒:
笔试所有系列文章均是记录本人的笔试题思路与代码,从中得到的启发和从别人题解的学习到的地方,所以关于题目的解答,只是以本人能读懂为目标,如果大家觉得看不懂,那是正常的。如果对本文的某些知识有不同的观点,欢迎讨论。
题目链接:
第一题:字符串替换_牛客题霸_牛客网
第二题:神奇数_牛客笔试题_牛客网
第三题:DNA序列_牛客题霸_牛客网
---------------------------------------------------我是分割线---------------------------------------------------------------
---------------------------------------------------我是分割线---------------------------------------------------------------
---------------------------------------------------我是分割线---------------------------------------------------------------
---------------------------------------------------我是分割线---------------------------------------------------------------
---------------------------------------------------我是分割线---------------------------------------------------------------
第一题
思路:
根据题目也可以看出这是一道简单的模拟题,大家使用双指针模拟题目的过程就好。
不过需要注意的是我们在循环结束后还要判断一下填充的数组是否使用完全
代码:
class StringFormat {
public:string formatString(string A, int n, vector<char> arg, int m) {string str="";int j=0;for(int i=0;i<n;i++){if(A[i] == '%' || A[i] == 's'){str+=arg[j++];if(i+1<n)i++;}else {str+=A[i];}}while(j<m) str+=arg[j++];return str;}
};
---------------------------------------------------我是分割线---------------------------------------------------------------
---------------------------------------------------我是分割线---------------------------------------------------------------
---------------------------------------------------我是分割线---------------------------------------------------------------
第二题
思路:
也是一道比较简单的模拟题,我们第一思路,根据【a,b】范围内的数字,直接枚举每个数字,判断每个数字是否是神奇数。
接下来我们思考的就是如何判断是否是神奇数,我们可以直接将数字的每一位取出,组成两位数然后再判断两位数就好,那么该如何取出一个数的每一位呢?
有两种思路,一是直接%10,/10,二是将其转化为字符串,去字符串的每个位就好。
最后是如何判断一个两位数是否是质数,比较简单的方法是采用试除法,让数字除以【2,sqrt(数字)】就好,判断是否能整除。
还有就是可以直接在开始程序之前直接判断【10-99】中每个数是否是质数。
代码:
#include <iostream>
#include <cmath>
#include <vector>
#include <algorithm>
typedef long long ll;
using namespace std;
vector<bool> dp(100,false);bool check(ll x)
{vector<int> nums;while(x){nums.push_back(x%10);x/=10;}for(int i=0;i<nums.size();i++){for(int j=i+1;j<nums.size();j++){ll a=nums[i]*10+nums[j];ll b=nums[j]*10+nums[i];if(dp[a] || dp[b])return true;}}return false;
}
int main() {ll a=0,b=0;cin>>a>>b;ll count=0;for(int i=10;i<=99;i++){if(i % 2 !=0 && i % 3 != 0 && i %5 != 0 && i%7 != 0){dp[i]=true;}}for(int i=a;i<=b;i++){if(check(i)) count++;}cout<<count<<endl;return 0;
}
---------------------------------------------------我是分割线---------------------------------------------------------------
---------------------------------------------------我是分割线---------------------------------------------------------------
---------------------------------------------------我是分割线---------------------------------------------------------------
第三题
思路:
一道比较明显的滑动窗口题目,我们判断一下出窗口的条件,我们可以发现当我们的窗口大小超过N的时候,就需要将left右移,然后在更新结果,不过下面博主为了偷懒,发现暴力枚举也可以通过,所以就没有写成平常那种通过nums[left]来判断窗口的元素情况。
代码:
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;string str;
int N;double check(const string& str,int left,int right)
{int count=0;for(int i=left;i<=right;i++){if(str[i] == 'C' || str[i] == 'G'){count++;}}// cout<<count<<endl;return count*1000/(N);
}int main()
{cin>>str;cin>>N;int n=str.size();int left=0,right=N-1;string s;double x=0.0;while(left< n && right < n){double y=check(str,left,right);// cout<<y<<endl;if(x<y){// cout<<left<<":"<<N<<endl;s=str.substr(left,N);x=y;}left++,right++;}cout<<s<<endl;return 0;
}