笔试强训:Day3

一、牛牛冲钻五(模拟)

登录---专业IT笔试面试备考平台_牛客网

cpp 复制代码
#include<iostream>
using namespace std;
int main(){
    int t,n,k;
    string s;
    cin>>t;
    while(t--){
        cin>>n>>k>>s;
        int ret=0;//统计加了多少星
        for(int i=0;i<n;++i)
            if(s[i]=='L') --ret;
            else if(i-1>=0&&i-2>=0&&s[i-1]=='W'&&s[i-2]=='W') ret+=k;
            else ++ret;
        cout<<ret<<endl;
    }
}

二、最长无重复子数组(变长滑动窗口)

最长无重复子数组_牛客题霸_牛客网

cpp 复制代码
class Solution {
public:
    int hash[100001];//标记重复数
    int maxLength(vector<int>& arr) {
        int n=arr.size();
        int ret=0;
        for(int left=0,right=0;right<n;++right){
            ++hash[arr[right]];
            while(hash[arr[right]]>1) --hash[arr[left++]];
            ret=max(ret,right-left+1);//求最大 不需要在while里面更新 求最小才需要
        }
        return ret;
    }
};

三、重排字符串(贪心)

登录---专业IT笔试面试备考平台_牛客网

cpp 复制代码
//该题就是贪心 要先统计数量最多的那个
#include<iostream>
#include<string>
using namespace std;
int main(){
    int n;
    string s;
    cin>>n>>s;
    int hash[26]={0};//统计字符
    char maxchar;//记录最大字符
    int maxcount=0;//以及他的最大数量
    for(auto&ch:s)
        if(++hash[ch-'a']>maxcount){//找到更大的就更新一下
            maxcount=hash[ch-'a'];
            maxchar=ch;
        }
    //这个时候我们先看看是否超过了
    if(maxcount>(n+1)/2) cout<<"no"<<endl;
    else{
        cout<<"yes"<<endl;
        //开始按顺序填那个最多的
        int index=0;
        while(maxcount--){
            s[index]=maxchar;
            index+=2;
        }
        //继续填剩下的
        for(int i=0;i<26;++i)
            if(hash[i]&&i!=maxchar-'a')
                while(hash[i]--){
                    if(index>=n) index=1;
                    s[index]=i+'a';
                    index+=2;
                }
        cout<<s<<endl;
    }
}

四、乒乓球筐(哈希)

乒乓球筐__牛客网

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;

int main() {
   string a,b;
   while(cin>>a>>b){
   int hash[26]={0};
   for(auto&ch:a) ++hash[ch-'A'];
   bool ret=true;
   for(auto&ch:b) 
     if(--hash[ch-'A']<0){
        ret=false;
        break;
     }
    cout<<(ret?"Yes":"No")<<endl;//多组 不能return 那就用一个bool值
   }
}
// 64 位输出请用 printf("%lld")

五、组队竞赛(排序+贪心)

组队竞赛_牛客笔试题_牛客网

cpp 复制代码
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1e5+5;
int n;
long long a[N*3];
int main() {
    cin>>n;
    for(int i=0;i<n*3;++i) cin>>a[i];
    sort(a,a+3*n);//排序之后 我们就取倒数第二个人的成绩
    int pos=3*n-2,count=0;
    long long ret=0;
    while(++count<=n){
        ret+=a[pos];
        pos-=2;
    }
    cout<<ret<<endl;
}
// 64 位输出请用 printf("%lld")

六、删除相邻数字的最大分数(预处理+状态dp)

删除相邻数字的最大分数_牛客题霸_牛客网

cpp 复制代码
#include <iostream>
using namespace std;
//状态dp 也就是不可同时取
const int N=1e4+1;
int sum[N],f[N],g[N];//第一个是总和数组 第二个是i位置选了的dp数组  第二个是i位置不选的dp数组
int n;
int main() {
   cin>>n;
   int x;
   while(n--){
     cin>>x;
     sum[x]+=x;
   }
   //然后进行dp
   for(int i=1;i<N;++i){
      f[i]=g[i-1]+sum[i];//当前位置选了
      g[i]=max(f[i-1],g[i-1]);//当前位置没选
   }
   cout<<max(f[N-1],g[N-1])<<endl;
}
// 64 位输出请用 printf("%lld")

七、平方数(数学)

登录---专业IT笔试面试备考平台_牛客网

cpp 复制代码
#include<iostream>
#include<cmath>
using namespace std;
typedef long long LL;
int main(){
    LL x;
    cin>>x;
    LL a=sqrt(x);
    LL x1=a*a,x2=(a+1)*(a+1);
    if(x2-x>x-x1) cout<<x1<<endl;
    else cout<<x2<<endl;
}

八、**分组(枚举+二分)

登录---专业IT笔试面试备考平台_牛客网

cpp 复制代码
#include<iostream>
#include<unordered_map>
using namespace std;
int n,m;
unordered_map<int,int> cnt;//统计各个声部各有多少人数
bool check(int x){//查看每组最多x人的时候最少能分几组
    int g=0;
    for(auto&[a,b]:cnt)
        g+=b/x+(b%x!=0);
    return g<=m;
}
int main(){
    cin>>n>>m;
    int x;
    int hmax=0;//统计最多人数的声部
    for(int i=0;i<n;++i){
        cin>>x;
        hmax=max(hmax,++cnt[x]);
    }
    int kinds=cnt.size();//有多少种类
    if(kinds>m) cout<<-1<<endl;//种类太多的话就无法安排
    else{
//         for(int i=1;i<=hmax;++i) 暴力枚举 
//             if(check(i)){
//                 cout<<i<<endl;
//                 break;
//             }
        //二分
        int left=1,right=hmax;
        while(left<right){//左区间端点法
           int mid=left+(right-left)/2;
           if(check(mid)) right=mid;
           else left=mid+1;
        }
        cout<<left<<endl;
    }
}

九、【模板】拓扑排序

【模板】拓扑排序_牛客题霸_牛客网

cpp 复制代码
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
const int N=2e5+1;
int in[N];//统计入度信息
vector<vector<int>> edges(N);//每个点对应边的集合
queue<int> q;//进行bfs
vector<int> ret;//获取最终结果
int n,m,a,b;
int main() {
    cin>>n>>m;
    while(m--){//开始建图
       cin>>a>>b;
       edges[a].emplace_back(b);
       ++in[b];//统计入度信息
    }
    //此时图建完了 然后开始把所有入度为0的点都丢进去
    for(int i=1;i<=n;++i)
       if(in[i]==0) q.push(i);
    //开始进行bfs
    while(!q.empty()){
        int a=q.front();
        ret.emplace_back(a);
        q.pop();
        //把跟t有关的入度删了
        for(auto&b:edges[a])
           if(--in[b]==0) q.push(b);
    }
    //检查一下是否符合要求
    if(ret.size()!=n) cout<<-1;//说明不是有向无环图
    else{
        for(int i=0;i<n-1;++i) 
           cout<<ret[i]<<" ";
        cout<<ret[n-1];
    }
}
// 64 位输出请用 printf("%lld")

十、字符串替换(模拟)

字符串替换_牛客题霸_牛客网

cpp 复制代码
class StringFormat {
public:
    string formatString(string A, int n, vector<char> arg, int m) {
      string ret;
      int j=0;//用来标记参数列表
      for(int i=0;i<n;++i)
        if(A[i]=='%'){
            ret+=arg[j++];
            ++i;
        }
        else ret+=A[i];
      while(j<m) ret+=arg[j++];
      return ret; 
    }
};

十一、**神奇数(数学)

神奇数_牛客笔试题_牛客网

cpp 复制代码
#include <iostream>
#include <cmath>
#include <vector>
using namespace std;
bool isprimenum(int x){//判断该数是否是质数 用试除法
    if(x<2||x%2==0) return false;//偶数肯定不是质数
    int n=sqrt(x);
    for(int i=3;i<=n;i+=2)//奇数除以偶数肯定不能整除
       if(x%i==0) return false;
    return true;
}
bool check(int x){//判断是否是神奇数 
    vector<int> nums;
    while(x){
       nums.emplace_back(x%10);
       x/=10;
    }
    int n=nums.size();
    for(int i=0;i<n;++i)//枚举十位数 
      for(int j=0;j<n;++j)//枚举个位数
        if(i!=j&&nums[i]!=0&&isprimenum(nums[i]*10+nums[j]))
           return true;
    return false;
}
int a, b;
int main() {
    cin>>a>>b;
    int ret=0;
    for(int i=max(10,a);i<=b;++i)
       if(check(i)) ++ret;
    cout<<ret<<endl;
}
// 64 位输出请用 printf("%lld")

十二、DNA序列(定长滑动窗口)

DNA序列_牛客题霸_牛客网

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;
string s;
int N;//限定子串的长度
int main() {
    cin>>s>>N;
    int maxCount=0;//用来统计最大的count
    int Count=0;//用来统计窗口里的c+g
    int begin=-1;//用来统计初始位置
    int n=s.size();
    int left=0,right=0;//滑动窗口
    for(;right<N-1;++right)  //先把前n-1个进去
        Count+=(s[right]=='C'||s[right]=='G');
    for(;right<n;++right,++left){
        Count+=(s[right]=='C'||s[right]=='G');
        if(Count>maxCount){
            maxCount=Count;
            begin=left;
        }
        Count-=(s[left]=='C'||s[left]=='G');
    }
    cout<<s.substr(begin,N)<<endl;
}
// 64 位输出请用 printf("%lld")

十三、*小乐乐改数字(模拟)

小乐乐改数字_牛客题霸_牛客网

cpp 复制代码
#include <iostream>
#include <string>
using namespace std;
//'A' 的 ASCII 码是 65
//'a' 的 ASCII 码是 97
//'0' 的 ASCII 码是 48
//' ' (空格) 的 ASCII 码是 32
string s;
int main() {
   cin>>s;
   for(auto&ch:s)
     if(ch&1) ch='1';
     else ch='0';
   cout<<stoi(s)<<endl;//自动处理前导零
}
// 64 位输出请用 printf("%lld")

十四、*十字爆破(预处理+模拟)

登录---专业IT笔试面试备考平台_牛客网

cpp 复制代码
//可以提前把每行每列的值都给他存起来
#include<iostream>
using namespace std;
const int N=1e6+1;
typedef long long LL;
LL row[N],col[N];//统计每行每列的值
int n,m;
int main(){
    scanf("%d %d",&n,&m);
    LL nums[n][m];//这个用NN建的话空间太大了 
    for(int i=0;i<n;++i)
        for(int j=0;j<m;++j){
            scanf("%lld",&nums[i][j]);
            row[i]+=nums[i][j];
            col[j]+=nums[i][j];
        }
    //开始尝试打印
    for(int i=0;i<n;++i){
        for(int j=0;j<m;++j)
            printf("%lld ",row[i]+col[j]-nums[i][j]);
        printf("\n");
    }
}

十五、**比那名居的桃子(定长滑动窗口/前缀和)

登录---专业IT笔试面试备考平台_牛客网

解法1:定长滑动窗口

cpp 复制代码
#include<iostream>
using namespace std;
typedef long long LL;
const int N=1e5+10;
LL h[N],s[N];
int n,k;
//滑动窗口 维护一个k长度的区间
int main(){
    cin>>n>>k;
    for(int i=1;i<=n;++i) cin>>h[i];
    for(int i=1;i<=n;++i) cin>>s[i];
    //先让前面k-1个进去
    int left=1,right=1;//滑动窗口
    LL hsum=0,ssum=0,hmax=0,smin=0,begin=0;
    for(;right<k;++right){
        hsum+=h[right];
        ssum+=s[right];
    }
    for(;right<=n;++left,++right){
        hsum+=h[right];
        ssum+=s[right];
        if(hsum>hmax){//如果快乐值更多 就得更新
            begin=left;
            hmax=hsum;
            smin=ssum;
        }
        else if(hsum==hmax&&ssum<smin){//如果快乐值一样 羞耻值少 也得更新
            begin=left;
            smin=ssum;
        }
        //出窗口
        hsum-=h[left];
        ssum-=s[left];
    }
    cout<<begin<<endl;
}

解法2:前缀和

cpp 复制代码
#include<iostream>
using namespace std;
typedef long long LL;
const int N=1e5+10;
LL h[N],s[N];
int n,k;
//滑动窗口 维护一个k长度的区间
int main(){
    cin>>n>>k;
    int x;
    for(int i=1;i<=n;++i){
        cin>>x;
        h[i]=h[i-1]+x;
    }
    for(int i=1;i<=n;++i){
        cin>>x;
        s[i]=s[i-1]+x;
    }
    //先让前面k-1个进去
    LL hmax=0,smin=0,begin=0;
    for(int i=k;i<=n;++i)
        if(h[i]-h[i-k]>hmax){
            begin=i-k+1;
            hmax=h[i]-h[i-k];
            smin=s[i]-s[i-k];
         }
         else if(h[i]-h[i-k]==hmax&&s[i]-s[i-k]<smin){
            begin=i-k+1;
            smin=s[i]-s[i-k];
         }
    cout<<begin<<endl;
}

十六、压缩字符串1(双指针)

压缩字符串(一)_牛客题霸_牛客网

cpp 复制代码
class Solution {
public:
    string compressString(string param) {
       int n=param.size();
       if(n<2) return param;
       string ret;//处理返回结果
       for(int i=0;i<n;){
          int j=i+1,count=1;
          while(j<n&&param[j]==param[i]){
                ++j;
                ++count;
          }
          ret+=param[i];
          if(count>1) ret+=to_string(count);
          i=j;
       }
       return ret;
    }
};

十七、**chika和蜜柑(重写排序)

登录---专业IT笔试面试备考平台_牛客网

cpp 复制代码
#include<iostream>
#include<algorithm>
using namespace std;
const int N=2e5+10;
typedef long long LL;
typedef pair<LL,LL> PLL;
PLL a[N];//酸度和甜度的数组
int n,k;
int main(){
    cin>>n>>k;
    for(int i=0;i<n;++i) cin>>a[i].first;
    for(int i=0;i<n;++i) cin>>a[i].second;
    sort(a,a+n,[&](const PLL&a,const PLL&b){
       return a.second==b.second?a.first<b.first:a.second>b.second; 
    });
    LL s=0,t=0;
    for(int i=0;i<k;++i){
        s+=a[i].first;
        t+=a[i].second;
    }
    cout<<s<<" "<<t<<endl;
}

十八、01背包

01背包_牛客题霸_牛客网

cpp 复制代码
class Solution {
public:
    int dp[1010]={0};
    int knapsack(int V, int n, vector<vector<int> >& vw) {
       //体积不超过V的情况下 当前能够装下的最大重量
       //dp[i][j]表示从前i个物品选,体积不超过j的最大重量
       for(int i=0;i<n;++i)
         for(int j=V;j>=vw[i][0];--j)
           dp[j]=max(dp[j],dp[j-vw[i][0]]+vw[i][1]);
       return dp[V];
    }
};
相关推荐
achene_ql13 分钟前
C++ 与 Lua 联合编程
开发语言·c++·lua
CodeWithMe35 分钟前
【中间件】brpc_基础_bthread头文件
c++·中间件·rpc
哈全网络1 小时前
如何使用 DeepSeek 帮助自己的工作?
人工智能·算法·ai编程·ai写作
weniry1 小时前
动态库与静态库的区别
开发语言·c++
Le_ee2 小时前
数据结构6 · BinaryTree二叉树模板
数据结构·c++·算法
李匠20242 小时前
C++负载均衡远程调用学习之TCP连接封装与TCPCLIENT封装
c++·网络协议·学习·tcp/ip
小宋要上岸3 小时前
优雅关闭服务:深入理解 SIGINT / SIGTERM 信号处理机制
c++·信号处理·grpc
EanoJiang3 小时前
算法
不太可爱的叶某人3 小时前
【学习笔记】深入理解Java虚拟机学习笔记——第2章 Java内存区域与内存溢出异常
java·jvm·笔记·学习
李匠20244 小时前
C++学习之shell高级和正则表达式
c++·学习