crazy search
给出一个字符串,共包含NC种字符,求这个字符串中长度为N的子串(不包含重复)的数量。题目中假设该字串个数不超过16000000个。输入第一行包含两个数字,分别为N\NC。第二行输入字符串,输出符合要求的子串个数。
输入样例:
3 4
daababac
输出样例:
给出一个字符串,共包含NC种字符,求这个字符串中长度为N的子串(不包含重复)的数量。题目中假设该字串个数不超过16000000个。输入第一行包含两个数字,分别为N\NC。第二行输入字符串,输出符合要求的子串个数。
输入样例:
3 4
daababac
输出样例:
5
这一题应该比较简单,是一个编码问题,将字符串编成NC进制数,开一个bool数组表示是否重复。
编码我是直接按ascii码开一个256的数组,记一个全局变量,按照出现的顺序进行编码(10以上的编码也是可以的)
pow最好自己写(用库函数总容易超时),string也不宜使用。
代码如下:
#include<cstdio>
#include<cstring>
char input[16000001] = { '\0' };
int p[256];//编码标准
int unrepeat = 0, plen = 0;
int pow(int a, int b)
{
if (b == 0)return 1;
if (b == 1)return a;
int res = a;
for (int i = 2; i <= b; i++)
res *= a;
return res;
}
int trans(int n1, char * x, int *p, int xlen)//x待转换的数,p编码标准,xlen是x的长度,n1进制(转10)
{
int ten = 0;
for (int i = 0; i < xlen; i++)
{
int ascII = x[i];
if (p[ascII] == 26)
{
p[ascII] = plen++;
}
ten += p[ascII]*pow(n1, xlen - i - 1);
}
return ten;
}
int main()
{
for (int i = 0; i < 256; i++)
p[i] = 26;
int N, NC;
scanf("%d%d", &N, &NC);//N字串长度,NC字符种数,NC进制编码,NC^N数组大小
scanf("%s", input);
int maxnum = pow(NC, N);
bool* repeat = new bool[maxnum];
for (int i = 0; i < maxnum; i++)
repeat[i] = false;
char* input2 = new char[N];
int len = strlen(input);
for (int i = 0; i <= len - N; i++)
{
for (int j = 0; j < N; j++)
{
input2[j] = input[i + j];
}
int m = trans(NC, input2, p, N);
if (!repeat[m])
{
repeat[m] = true;
unrepeat++;
}
}
printf("%d", unrepeat);
delete[] repeat;
delete[] input2;
return 0;
}