A (HDU - 2087)
#include
#include
#include
using namespace std;
int nexta[1006];
char t[1006],s[1006];
void getnexta(char s[])
{
memset(nexta,0,sizeof(nexta));
int n = strlen(s);
int k = -1,j = 0;
nexta[0] = -1;
while(j < n )
{
if(k == -1 || s[k] == s[j])
{
nexta[j + 1] = k + 1;
j ++;
k ++;
}
else
{
k = nexta[k];
}
}
}
int kmp(char s[],char t[])//t模式串,s母串.此种为返回首次匹配的位置,不能匹配则返回-1.
{
getnexta(t);
int ans = 0;
int n = strlen(s),m = strlen(t);
int i = 0,j = 0;
while(i < n && j < m)
{
if(j == -1 || s[i] == t[j])
{
i ++;
j ++;
}
else
{
j = nexta[j];
}
if(j == m)//根据题目要求改变
{
ans ++;
j = 0;
}
}
return ans;
}
int main()
{
// freopen("in.txt","r",stdin);
while(1)
{
scanf("%s",s);
if(strcmp(s,"#") == 0)
break;
scanf("%s",t);
printf("%d\n",kmp(s,t));
}
return 0;
}
B(HDU - 1711)
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
C(HDU - 1686)
- kmp统计子串格式
- 可重叠
- 注意匹配成功之后
j=nexta[j]
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
D(HDU - 3746)
- next数组的一共经典应用,统计字符串的循环节
- 希望大家这道题都能搞明白
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
E(HDU - 1251)
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
F(HihoCoder - 1366)
- 本来想让大家试着用字典树做,但时限给了10s,自然也就能用stl直接做
- 正序查找,倒叙插入
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
G(UVA - 12338)
- 提议是询问两个字串的最长前缀匹配
- 符串hash+二分,hash的一个经典应用
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
H(HDU - 4300)
- 给一个代换表,给一个混合明密文,密文完整明文缺失,问要补充的最小字符数
- 两个hash,假设全部是密文,翻译过来之后计算hash,已经翻译之前计算hash。从len/2枚举密文长度,翻译后的密文前缀和翻译前的明文后缀
- 扩展kmp也可做
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include
J(HDU - 4825)
- 从已知集合中选一个数是的询问中的数与选的这个数的异或值最大
- 01字典树,从高位到低位建树,贪心
# include
# include
# include
# include
# include
# include
# include
# include
# include
# include