牛客竞赛每日俩题 - Day3

简介: 牛客竞赛每日俩题 - Day3

动态规划思想

查找两个字符串a,b中的最长公共子串_牛客题霸_牛客网

思路:


       本题需要用动态规划求解,MCS[i][j] 记录短字符串 s1 前 i 个字符和长字符串 s2 前 j 个字符的最长子串的长度,初始化所有值为 0 。当 s1[i-1] = s2[j-1] 时, MCS[i][j] = MCS[i - 1][j - 1] + 1 ,这里使用一个额外的值 start 来记录最长子串在短字符串 s1 中出现的起始位置, maxlen 记录当前最长子串的长度,当 MCS[i][j] > maxlen 时, maxlen = MCS[i][j] , 则 start = i - maxlen ;档 s1[i-1] != s2[j-1] 时不需要任何操作,最后获取 substr(start, maxlen) 即为所求

1、转移方程为:   如果遍历到的该位两个字符相等,则此时长度等于两个前一位长度+1,

(dp[i][j]=dp[i−1][j−1]+1),如果遍历到该位时两个字符不相等,则置为0,因为这是子串,必须连续相等,断开要重新开始。

2、

vector<vector<int>> MSC(len1+1,vector<int>(len2+1,0));

解析:

用vector构造二维数组,用len2+1构造行并全部初始化为0,用vector<int>(len2+1,0)(初始化为0的行)构造len1+1个列;即:将整个数组初始化为0

(建议先看第二题)

#include <iostream>
#include<vector>
using namespace std;
string getcomsubstr(string &s1,string &s2)
{
    if(s1.size()>s2.size())
        swap(s1,s2);//要输出在较短串中最先出现的
    int len1=s1.size();
    int len2=s2.size();
    vector<vector<int>> MSC(len1+1,vector<int>(len2+1,0));
    int start=0,maxsize=0;
    for(int i=1;i<=len1;i++)    //一较短串为基础,才能找较短串中最先出现的
        for(int j=1;j<=len2;j++)
        {
            if(s2[j-1]==s1[i-1]) 
                MSC[i][j]=MSC[i-1][j-1]+1;
            if(MSC[i][j]>maxsize)//有更长公共子串,更新长度
            {
                maxsize=MSC[i][j];
                //以i结尾的最大长度max,则起始位置为i-max
                start=i-maxsize;
            }
        }
        return s1.substr(start,maxsize);
}
int main() 
{
    string str1,str2;
    while(cin>>str1>>str2)
    {
        string sub=getcomsubstr(str1,str2);
        cout<<sub<<endl;
    }
    return 0;
}

经典DP

公共子串计算_牛客题霸_牛客网

思路:


       求最大公共子串,使用递推实现 假设 x(i): 字符串第 i 个字符 y(j): 字符串第 j 个字符 dp[i][j]: 以 x(i),y(j) 结尾的最大子串长度 比如: x: "abcde" y:"bcdae" dp[2][1]: 以 x(2),y(1) 结尾的最大子串长度 即: x 遍历到 "abc", y 遍历 到 "bc", 都以字符 'c' 结尾时最大公共子串为 "bc" 故:当计算 dp[i][j] 时,首先看 x(i),y(j) 的值:

( 1 ) : x(i) == y(j) 当前两个字符串结尾的字符相等, dp[i][j] = dp[i-1][j-1] + 1 即个它的长度加 1 (2 ) : x(i) != y(j) 当前两个字符 串结尾的字符不相等,说明没有以这连个字符结尾的公共子串 即 dp[i][j] = 0

(3 ) : dp[0][j] 和 dp[i][0] 表示以 某个子串的第一个字符结尾,最大长度为 1 如果 x(0) == y(j) 或者 x(i) == y(0), 则长度为 1 ,否则为 0 当 dp 中的 所有元素计算完之后,从中找打最大的值输出

#include <iostream>
#include<vector>
using namespace std;
int getcomsubstr(string &s1,string &s2)
{
    int len1=s1.size();
    int len2=s2.size();
    vector<vector<int>> MSC(len1+1,vector<int>(len2+1,0));
    int start=0,maxsize=0;
    for(int i=1;i<=len1;i++)   
        for(int j=1;j<=len2;j++)
        {
            if(s2[j-1]==s1[i-1]) 
                MSC[i][j]=MSC[i-1][j-1]+1;
            if(MSC[i][j]>maxsize)//有更长公共子串,更新长度
            {
                maxsize=MSC[i][j];
            }
        }
        return maxsize;
}
int main() 
{
    string str1,str2;
    while(cin>>str1>>str2)
    {
        int maxv=getcomsubstr(str1,str2);
        cout<<maxv<<endl;
    }
    return 0;
}

简单的数学问题

洗牌_牛客题霸_牛客网

看到题目字数和样例人麻了?其实只是一道小学奥数题


思路:


每次读取一个数之后,算出他经过 k 次洗牌后的位置,只用一个长度为 2n 数组用来输出

根据当前数的位置,可以算出经过一次洗牌后的位置

如果当前数小于等于n(即在左手),则他下次出现的位置是 2*当前位置

与之对应的当前位置 + n(即在右手)的牌,则他下次出现的位置是 2*当前位置 + 1

高效率地把一个数组的内容复制给另一个数组:

#include <stdio.h>
#define SIZE 3
int main()
{
  int a[SIZE], b[SIZE]={1,2,3};
  register int *x, *y;
  for( x = a, y = b ; y < &b[SIZE] ; )
    *x++ = *y++;
  return 0;
}
#include <iostream>
using namespace std;
int main() {
    int T,n,k;
    cin>>T;
    while(T--)
    {
        cin>>n>>k;
        int num=2*n;
        int card[num+1];
        for(int i=0;i<num;i++) cin>>card[i];
        while(k--)
        {
            int tmp[num+1];
            int *x,*y;
            for(x=tmp,y=card;y<&card[num+1];) *x++=*y++;
            for(int j=0;j<n;j++)
            {
                card[2*j]=tmp[j];    //左手的牌排放的位置
                card[2*j+1]=tmp[j+n];//右手的牌排放的位置
            }
        }
        for(int i=0;i<num-1;i++) cout<<card[i]<<" ";
        cout<<card[num-1]<<endl;
    }
}
// 64 位输出请用 printf("%lld")
相关文章
|
19天前
|
存储
每日一题——leetcode682.棒球比赛
每日一题——leetcode682.棒球比赛
|
11月前
|
测试技术 数据库
牛客竞赛每日俩题 - Day12
牛客竞赛每日俩题 - Day12
|
11月前
牛客竞赛每日俩题 - Day9
牛客竞赛每日俩题 - Day9
|
11月前
|
算法
牛客竞赛每日俩题 - Day14
牛客竞赛每日俩题 - Day14
|
11月前
|
容器
牛客竞赛每日俩题 - Day10
牛客竞赛每日俩题 - Day10
|
11月前
牛客竞赛每日俩题 - Day1
牛客竞赛每日俩题 - Day1
|
11月前
牛客竞赛每日俩题 - Day6
牛客竞赛每日俩题 - Day6
牛客竞赛每日俩题 - Day6
|
11月前
|
人工智能 BI
牛客竞赛每日俩题 - Day4
牛客竞赛每日俩题 - Day4
牛客竞赛每日俩题 - Day4
|
11月前
|
机器学习/深度学习
牛客竞赛每日俩题 - Day8
牛客竞赛每日俩题 - Day8
|
11月前
牛客竞赛每日俩题 - Day2
牛客竞赛每日俩题 - Day2