【kmp专题】牛客网子串(进制转化+kmp/string.find())

题目地址:https://ac.nowcoder.com/acm/problem/13253

题目描述 


给出一个正整数n,我们把1..n在k进制下的表示连起来记为s(n,k),例如s(16,16)=123456789ABCDEF10, s(5,2)=11011100101。现在对于给定的n和字符串t,我们想知道是否存在一个k(2 ≤ k ≤ 16),使得t是s(n,k)的子串。
输入描述:
第一行一个整数n(1 ≤ n ≤ 50,000)。
第二行一个字符串t(长度 ≤ 1,000,000)
输出描述:
"yes"表示存在满足条件的k,否则输出"no"
示例1
输入
8
01112
输出
yes

解题思路:


把1~n转化成对应的2~16进制序列,再在该序列中查找是否存在字符串t

进制转化方法:

1.用int数组存对应的进制序列,再将int数组转化为char[],分0~9和10~15两中情况转化成对应的字符,获得最终进制序列

2.用string存转化后的最终进制序列,利用string的+操作(int->char的转变)

寻找子串方法:

1.kmp算法

2.如果用的是string存最终进制序列,则可以使用string.find(t)!=string::npos判断存在,时间复杂度为O(n*m),这种方法在这道题里不会超时。也可以使用kmp,时间复杂度为O(n+m)

ac代码:


string+string.find()

#include 
#define maxn 5005
#define inf 0x3fffffff
using namespace std;
typedef long long ll;
char to_des(int x)
{

    if(x>=0&&x<=9)
        x=x+'0';
    else if(x>=10&&x<=15)
        x=x-10+'A';
    return (char)x;
}
string num_to_string(int des,int num)
{
    string a;
    while(num>0)
    {
        int x=num%des;
        a=to_des(x)+a;
        num/=des;
    }
    return a;
}
int n;
string t;
int main()
{
    scanf("%d", &n);
    cin >> t;
    bool flag = false;
    for (int i = 2; i <= 16; i++)
    {
        string s;
        for (int j = 1; j <= n; j++)
            s+= num_to_string(i, j);
        if (s.find(t) != string::npos) {
            flag = true;
            break;
        }
    }
    if (flag) printf("yes");
    else printf("no");
    return 0;
}

string+kmp()

#include 
#define maxn 1000005
#define inf 0x3fffffff
using namespace std;
typedef long long ll;
int Next[maxn];
int n;
string t;
char to_des(int x)
{
    if(x>=0&&x<=9)
        x=x+'0';
    else if(x>=10&&x<=15)
        x=x-10+'A';
    return (char)x;
}
string num_to_string(int des,int num)
{
    string a;
    while(num>0)
    {
        int x=num%des;
        a=to_des(x)+a;
        num/=des;
    }
    return a;
}
void set_Next()
{
    int j=0,k=-1;
    Next[0]=-1;
    while(j> t;
    set_Next();
    bool flag = false;
    for (int i = 2; i <= 16; i++)
    {
        string s;
        for (int j = 1; j <= n; j++)
            s+= num_to_string(i, j);
        if(kmp(s,t))
        {
            flag = true;
            break;
        }
    }
    if (flag) printf("yes");
    else printf("no");
    return 0;
}

int[]+char[]+kmp  来源:https://me.csdn.net/mengxiang000000

#include
#include
#include
using namespace std;
char a[3000050];
char b[1000050];
int nex[3000050];
int lena,lenb;
void set_naxt()//子串的nex数组
{
    int i=0,j=-1;
    nex[0]=-1;
    while(i=0;j--)
                {
                    if(num[j]<10)
                    a[lena++]=num[j]+'0';
                    else a[lena++]=num[j]-10+'A';
                }
            }
            ans=max(ans,kmp());
            if(ans>0)break;
        }
        if(ans>0)printf("yes\n");
        else printf("no\n");
    }
}

 

你可能感兴趣的:(kmp)