笔试强训:Day2

一、字符串中找出连续最长的数字串(双指针)

字符串中找出连续最长的数字串_牛客题霸_牛客网

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

int main() {
    //双指针
    string str;
    cin>>str;
    int n=str.size();
    int begin=-1,len=0;
    for(int left=0;left<n;++left)
        if(isdigit(str[left])){//如果left是数字的话
           int right=left;
           while(right<n&&isdigit(str[right])) ++right;
           //走到这说明right在结尾的下一个位置
           if(right-left>len){
            begin=left;
            len=right-left;
           }
           left=right;//再++left 没事 因为该位置一定不是数字 可以跳过
        }
    if(begin==-1) cout<<""<<endl;
    else cout<<str.substr(begin,len)<<endl;
}
// 64 位输出请用 printf("%lld")

二、岛屿数量(bfs/dfs)

岛屿数量_牛客题霸_牛客网

cpp 复制代码
class Solution {
public:
    int m,n;
    int dx[4]={0,0,-1,1};
    int dy[4]={-1,1,0,0};
    int solve(vector<vector<char>>& grid) {
       m=grid.size(),n=grid[0].size();
       int ret=0;
       for(int i=0;i<m;++i)
         for(int j=0;j<n;++j)
           if(grid[i][j]=='1'){
              ++ret;//说明找到了一个岛屿
              dfs(grid,i,j);
           }
       return ret;
    }
    void dfs(vector<vector<char>>& grid,int i,int j){
        grid[i][j]='0';
        for(int k=0;k<4;++k){
            int x=dx[k]+i,y=dy[k]+j;
            if(x>=0&&x<m&&y>=0&&y<n&&grid[x][y]=='1') 
               dfs(grid,x,y);
        }
    }
};

三、**拼三角(优化枚举)

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

cpp 复制代码
#include<iostream>
#include<algorithm>//算法头文件 记得会拼
//优化后的枚举 只需要考虑4种情况
//012-345 023-145 034-125 045-123
int a[6];
using namespace std;
int main(){
    int t;
    cin>>t;
    while(t--){
        for(int i=0;i<6;++i) cin>>a[i];
        sort(a,a+6);//静态数组的用法
        if(a[0]+a[1]>a[2]&&a[3]+a[4]>a[5]||
           a[0]+a[2]>a[3]&&a[1]+a[4]>a[5]||
           a[0]+a[3]>a[4]&&a[1]+a[2]>a[5]||
           a[0]+a[4]>a[5]&&a[1]+a[2]>a[3])  cout<<"Yes"<<endl;
        else cout<<"No"<<endl;
    }
}

四、**最小公倍数&最大公约数(数学)

求最小公倍数_牛客题霸_牛客网

cpp 复制代码
#include <iostream>
using namespace std;
int gcd(int a,int b){//32%26=6  26%6=2  6%2=0 2%0
    if(b==0) return a;
    return gcd(b,a%b);
}
int main() {
   int a,b;
   cin>>a>>b;
   cout<<(a*b/gcd(a,b))<<endl;
}
// 64 位输出请用 printf("%lld")

五、**数组中的最长连续子序列(排序+双指针)

数组中的最长连续子序列_牛客题霸_牛客网

cpp 复制代码
class Solution {
public:
//可以直接排序 但是要处理 值相等的情况 1 1 2 3 4 5 5 5 5 6        
    int MLS(vector<int>&nums) {
        int n=nums.size();
        sort(nums.begin(),nums.end());
        int ret=1;
        //双指针 我可以先找到第一个比前面大1的那个数
        for(int left=0;left<n;){
            int right=left+1,count=1;//
            while(right<n){
                if(nums[right-1]+1==nums[right]){
                    ++count;
                    ++right;
                }
                else if(nums[right-1]==nums[right]) ++right;
                else break;
            }
            ret=max(ret,count);
            left=right;
        }
        return ret;
    }
};

六、字母搜集(路径dp)

字母收集_牛客题霸_牛客网

cpp 复制代码
#include <iostream>
using namespace std;
const int N=501;
char nums[N][N];
int dp[N][N];
int main() {
   int m,n;
   cin>>n>>m;
   for(int i=1;i<=n;++i)
     for(int j=1;j<=m;++j)
       cin>>nums[i][j];
   for(int i=1;i<=n;++i)
     for(int j=1;j<=m;++j){
        int t=0;
        if(nums[i][j]=='l') t=4;
        else if(nums[i][j]=='o') t=3;
        else if(nums[i][j]=='v') t=2;
        else if(nums[i][j]=='e') t=1;
        dp[i][j]=max(dp[i-1][j],dp[i][j-1])+t;
     }
    cout<<dp[n][m]<<endl;
}
// 64 位输出请用 printf("%lld")

七、添加逗号(模拟)

添加逗号_牛客题霸_牛客网

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

int main() {
    string s;
    cin>>s;
    string ret;//统计最后结果
    int n=s.size();
    for(int i=0;i<n;++i){
        ret+=s[i];
        if((n-i-1)%3==0&&i!=n-1) ret+=',';
    }
    cout<<ret<<endl;
}
// 64 位输出请用 printf("%lld")

八、跳台阶(线性dp)

跳台阶_牛客题霸_牛客网

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

int main() {
   int n;
   cin>>n;
   if(n<=2) cout<<n<<endl;
   else{
      int a=1,b=2,c; //dp[1]=1 dp[2]=2  dp[3]=dp[1]+dp[2];
      for(int i=3;i<=n;++i){
        c=a+b;
        a=b;
        b=c;
      }
      cout<<c<<endl;
   }
}

九、**扑克牌顺子(排序/位图+模拟)

扑克牌顺子_牛客题霸_牛客网

解法1:排序+模拟

cpp 复制代码
class Solution {
public:
    bool IsContinuous(vector<int>& nums) {
        //要对数组排序 同时统计0的个数 若相邻数字的空缺总数<=0的个数 那就是连续的
        sort(nums.begin(),nums.end());
        int zero=0;//统计0
        int i=0;
        while(nums[i]==0){
            ++zero;
            ++i;
        }
        int dis=0;//统计距离
        //记录五张牌中最大值max到最小值min的距离
        for(;i<4;++i){
            if(nums[i]==nums[i+1]) return false;
            dis+=nums[i+1]-nums[i]-1;
        }
        if(zero>=dis) return true;
        return false;
    }
};

解法2:找规律+位图

cpp 复制代码
class Solution {
public:
    bool IsContinuous(vector<int>& nums) {
        int flag=0;
        int _min=14,_max=0;
        for(auto&e:nums){
            if(e==0) continue;
            if(flag&(1<<e)) return false;//说明重复了
            flag|=(1<<e);//标记这张票出现过了
            _min=min(_min,e);//最小牌
            _max=max(_max,e);//最大牌
        }
        return _max-_min<5;
    }
};

十、**最长回文子串(动归/马拉松/中心扩展)

最长回文子串_牛客题霸_牛客网

cpp 复制代码
class Solution {
public:
//中心扩展算法
    int getLongestPalindrome(string A) {
        int n=A.size();
        int ret=1;
        for(int i=1;i<n;++i){
            //当长度是奇数的时候
            int left=i-1,right=i+1;
            while(left>=0&&right<n&&A[left]==A[right]){
                --left;
                ++right;
            }
            ret=max(ret,right-left-1);
            //当长度是偶数的时候
            left=i-1,right=i;
            while(left>=0&&right<n&&A[left]==A[right]){
                --left;
                ++right;
            }
            ret=max(ret,right-left-1);
        }
        return ret;
    }
};

十一、买卖股票的最好时机1(贪心)

买卖股票的最好时机(一)_牛客题霸_牛客网

cpp 复制代码
#include <iostream>
using namespace std;
const int N=1e5+1;
int a[N];
int main() {
   int n;
   cin>>n;
   for(int i=0;i<n;++i) cin>>a[i];
   int prevmin=a[0];//记录前面的最小值
   int ret=0;//记录最大利润 有可能是逆序的 所以结果就是0
   for(int i=1;i<n;++i){
      ret=max(ret,a[i]-prevmin);
      prevmin=min(prevmin,a[i]);
   }
   cout<<ret<<endl;
}
// 64 位输出请用 printf("%lld")

十二、**过河卒(路径dp)

[NOIP2002 普及组] 过河卒_牛客题霸_牛客网

cpp 复制代码
#include <iostream>
#include <cmath>
using namespace std;
long long dp[22][22];
int main() {
    int n,m,x,y;
    cin>>n>>m>>x>>y;
    x+=1,y+=1;//因为有虚拟节点
    dp[0][1]=1;
    for(int i=1;i<=n+1;++i)
      for(int j=1;j<=m+1;++j)
        if(i!=x&&j!=y&&abs(i-x)+abs(j-y)==3||i==x&&j==y) dp[i][j]=0;
        else dp[i][j]=dp[i-1][j]+dp[i][j-1];
    cout<<dp[n+1][m+1]<<endl;
}
// 64 位输出请用 printf("%lld")

十三、**游游的水果大礼包(枚举)

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

cpp 复制代码
//一般来说枚举有三种方法 
//1、选几个就用几个for循环  如果选超过3个以上的基本不适用
//2、用dfs把位置摆出来 然后尝试去填
//3、根据某些特性优化枚举  或者数量少的直接用if else
#include<iostream>
using namespace std;
int main(){
    long long n,m,a,b;
    cin>>n>>m>>a>>b;
    long long ret=0;
    //我们先尝试枚举1号
    for(int x=0;x<=min(n/2,m);++x){
        int y=min(n-x*2,(m-x)/2);
        ret=max(ret,a*x+b*y);
    }
    cout<<ret<<endl;
}

十四、**买卖股票的最好时机2(贪心/双指针)

买卖股票的最好时机(二)_牛客题霸_牛客网

解法1:双指针

cpp 复制代码
#include <iostream>
using namespace std;
const int N=1e5+3;
int a[N];
int n;
int main() {
  cin>>n;
  int ret=0;
  for(int i=0;i<n;++i) cin>>a[i];
  for(int i=0;i<n;++i){
      int j=i;
      while(j+1<n&&a[j+1]>a[j]) ++j;
      //此时j正好在顶点
      ret+=a[j]-a[i];
      i=j;
  }
  cout<<ret<<endl;
}
// 64 位输出请用 printf("%lld")

解法2:贪心:把交易拆成一天一天

cpp 复制代码
#include <iostream>
using namespace std;
const int N=1e5+3;
int a[N];
int n;
int main() {
  cin>>n;
  int ret=0;
  for(int i=0;i<n;++i) cin>>a[i];
  for(int i=1;i<n;++i)
    if(a[i]>a[i-1]) ret+=a[i]-a[i-1];
  cout<<ret<<endl;
}
// 64 位输出请用 printf("%lld")

十五、倒置字符串(双指针)

倒置字符串_牛客题霸_牛客网

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

int main() {
    string s;
    //先整体逆置 在局部逆置
    getline(cin,s);
    reverse(s.begin(),s.end());
    int n=s.size();
    for(int left=0;left<n;++left){
        int right=left;
        while(right<n&&s[right]!=' ') ++right;
        //开始逆置
        reverse(s.begin()+left,s.begin()+right);
        left=right;
    }
    cout<<s<<endl;
}
// 64 位输出请用 printf("%lld")

十六、删除公共字符(哈希)

删除公共字符_牛客题霸_牛客网

cpp 复制代码
#include <iostream>
using namespace std;
int main() {
   string s,t;
   getline(cin,s);
   getline(cin,t);
   bool hash[128]={0};
   for(char ch:t) hash[ch]=true;
   string ret;
   for(auto&ch:s) if(!hash[ch]) ret+=ch;
   cout<<ret<<endl;
}
// 64 位输出请用 printf("%lld")

十七、**两个链表的第一个公共结点(模拟)

两个链表的第一个公共结点_牛客题霸_牛客网

解法1:计数 然后让长的先走 然后再一起走

cpp 复制代码
class Solution {
  public:
    ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
        if (!pHead1 || !pHead2) return nullptr;
        if(pHead1==pHead2) return pHead1;
        ListNode*cur1=pHead1,*cur2=pHead2;
        int a=0,b=0;
        while(cur1){
          cur1=cur1->next;
          ++a;
        }
        while(cur2){
          cur2=cur2->next;
          ++b;
        }
        //长的先走count2-count1步
        cur1=pHead1,cur2=pHead2;
       int m=a>b?b:a;
       while(a-m){
          cur1=cur1->next;
          --a;
        }
        while(b-m){
          cur2=cur2->next;
          b--;
        }
        while(cur1!=cur2){
            cur1=cur1->next;
            cur2=cur2->next;
        }
        return cur1;
    }
};

解法2:等价关系(数学特性)

cpp 复制代码
class Solution {
  public:
    ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
        if (!pHead1 || !pHead2) return nullptr;
        if(pHead1==pHead2) return pHead1;
        ListNode*cur1=pHead1,*cur2=pHead2;
        while(cur1!=cur2){
            cur1=cur1?cur1->next:pHead2;
            cur2=cur2?cur2->next:pHead1;
        }
        return cur1;
    }
};

解法3:借助set

cpp 复制代码
class Solution {
  public:
    ListNode* FindFirstCommonNode(ListNode* pHead1, ListNode* pHead2) {
        if (!pHead1 || !pHead2) return nullptr;
        if(pHead1==pHead2) return pHead1;
        unordered_set<ListNode*> s;
        while(pHead1){
            s.insert(pHead1);
            pHead1=pHead1->next;
        }
        while(pHead2){
            if(s.count(pHead2)) return pHead2;
            pHead2=pHead2->next;
        }
        return nullptr;
    }
};

十八、**mari和shiny(状态dp+优化)

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

cpp 复制代码
#include<iostream>
#include<string>
using namespace std;
int main(){
    int n;
    string str;
    cin>>n>>str;
    long long s=0,h=0,y=0;
    for(int i=0;i<n;++i){
        char ch=str[i];
        if(ch=='s')++s;
        else if(ch=='h')h+=s;
        else if(ch=='y')y+=h;
    }
    cout<<y<<endl;
}
相关推荐
梁下轻语的秋缘12 分钟前
每日c/c++题 备战蓝桥杯 ([洛谷 P1226] 快速幂求模题解)
c++·算法·蓝桥杯
CODE_RabbitV17 分钟前
【深度强化学习 DRL 快速实践】逆向强化学习算法 (IRL)
算法
每次的天空43 分钟前
kotlin与MVVM结合使用总结(三)
开发语言·microsoft·kotlin
虾球xz43 分钟前
游戏引擎学习第244天: 完成异步纹理下载
c++·学习·游戏引擎
BOB-wangbaohai43 分钟前
Flowable7.x学习笔记(十四)查看部署流程Bpmn2.0-xml
xml·笔记·学习
矛取矛求1 小时前
C++区别于C语言的提升用法(万字总结)
c语言·c++
mit6.8241 小时前
[贪心_7] 最优除法 | 跳跃游戏 II | 加油站
数据结构·算法·leetcode
keep intensify1 小时前
通讯录完善版本(详细讲解+源码)
c语言·开发语言·数据结构·算法
ephemerals__1 小时前
【c++11】c++11新特性(下)(可变参数模板、default和delete、容器新设定、包装器)
开发语言·c++
shix .1 小时前
2025年PTA天梯赛正式赛 | 算法竞赛,题目详解
数据结构·算法