hdu 3336 Count the string

点击打开链接hdu 3336

思路:kmp+next数组的应用

分析:
1 题目要求的是给定一个字符串s,求字符串s的所有的前缀在s的匹配的次数之和mod10007.
2 很明显n<= 200000,分析一下那么就要n个前缀如果每一个前最都去匹配s的话复杂度就是o(n^2),那么肯定是TLE的,所以要考虑另外的思路
3 我们知道next[j] = len,表示的是在前j个字符里前缀和后缀的最大的匹配的长度为len,所以根据next数组的性质,我们只要去枚举j的值从n->1,为什么要从n开始而不是1开始呢,这里因为是要求前缀的匹配数而不是后缀;
4 求sum的时候注意每一步都有可能超过范围,所以就要求一次sum同时取模一次。

代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;

#define MAXN 200010
#define MOD 10007

int t , n , sum;
int next[MAXN];
char pattern[MAXN];

void getNext(){
   next[0] = next[1] = 0;
   for(int i = 1 ; i < n ; i++){
      int j = next[i];
      while(j && pattern[i] != pattern[j])
          j = next[j];
      next[i+1] = pattern[i] == pattern[j] ? j+1 : 0;
   }
}

void solve(){
   sum = 0;
   for(int i = n ; i >= 1 ; i--){/*枚举i的值*/
      sum = (sum+1)%MOD;/*每一步取模*/
      int j = next[i];
      while(j){/*顺着nest数组求匹配的次数*/
         sum = (sum+1)%MOD;
         j = next[j];
      }
   }
   printf("%d\n" , sum);
}

int main(){
   scanf("%d" , &t);
   while(t--){
       scanf("%d" , &n);
       scanf("%s" , pattern);
       getNext();
       solve();
   }
   return 0;
}
时间: 2024-11-03 21:56:20

hdu 3336 Count the string的相关文章

算法题:HDU 3336 Count the string(经典,KMP+DP)

链接: http://acm.hdu.edu.cn/showproblem.php?pid=3336 题目大意: 给一个字符串,求出这个字符串的所有前缀出现的次数之和. 分析与总结 : 运用到了dp的思想,dp弱逼一个表示压力很大... 向这位博主大人学习了: http://www.cnblogs.com/yuelingzhi/archive/2011/08/03/2126346.html 找出前缀后,算出现 次数,很明显的是一个单模式串匹配问题,KMP 可以很好的解决,不过如果直接这样暴力的话

HDU3336 Count the string 一道KMP的巧解

http://acm.hdu.edu.cn/showproblem.php?pid=3336 题目 这是喵呜大神用KMP做的,46MS  #include <stdio.h> #define MOD 10007 char b[200005]; int dp[200005]; int p[200005]; int n; int Pre() { int s,i,j; dp[0]=1; j=-1; p[0]=-1; s=1; for (i=1;i<n;i++) { while(j>=0

HDOJ(HDU) 2137 circumgyrate the string(此题用Java-AC不过!坑)

此题如果有用JavaACDSee,请评论,谢谢了. Problem Description Give you a string, just circumgyrate. The number N means you just circumgyrate the string N times, and each time you circumgyrate the string for 45 degree anticlockwise. Input In each case there is string

hdu 4750 Count The Pairs 最小生成树

      比赛时候水了,一直打算算出22直接的关系数,然后又要考虑图不连通情况等等,搞了半天还没搞定.       其实只要一层一层慢慢加就可以了,最后结果离线或者在线处理一下均可以.       因为最长路的最小值就相当于最小值一个一个添加 贴一下第一个AC队的代码,思路很清晰: #include <cstdio> #include<iostream> #include <algorithm> using namespace std; typedef long lo

KMP专题【完结】

第一题 hdu 1711 Number Sequence 点击打开hdu 1711 思路: 1 kmp是用来匹配字符串,只能够匹配单一的字符串 2 kmp的算法的过程:   1:假设文本串的长度为n,模式串的长度为m:   2:先例用O(m)的时间去预处理next数组,next数组的意思指的是当前的字符串匹配失败后要转到的下一个状态:   3:利用o(n)的时间去完成匹配: 3 时间复杂度为o(n+m)即o(n): 点击查看代码 第二题 hdu 1686 oulipo 点击打开hdu 1686

Java的string类常量池及不可变性

1.String常量池     当使用new String("hello")时,JVM会先使用常量池来管理"hello"直接量,再调用String类的构造器来创建一个新的String对象,新创建的对象被保存在堆内存中.即new String("hello")一共产生了两个字符串对象. [常量池constant pool]管理在编译时被确定并保存在已编译的.class文件中的一些数据,包括关于类.方法.接口中的常量,和字符串常量.  [字符串常量池

String源码简析(未完成,待本周末更新)

类和接口 String类被定义成public final class,所以String类无法被继承. String类实现了Serializabel.Comparabe.CharSequence三个接口,分别对应着序列化.排序.字符串处理三个方面的功能. 类属性 String类底层有固定长度的字符数组组成,用hash的方法缓存字符串,含有一个序列化ID以及一个用于序列化的ObjectStreamField类,这个类我们会单独拿出一篇文章来讲. private final char value[];

c++-C++,如何将未知长度的string输入数组

问题描述 C++,如何将未知长度的string输入数组 如代码,我发现程序在运行时会跳过cin.get,这是怎么回事啊?另外,关于将未知长度的字符串输入数组,还有什么好办法吗? int main() { int time; scanf("%d", &time); int count=0; while(count < time) { string str; char temp; int i; while((temp=cin.get())!='n') { str +=temp

String、StringBuffer、StringBuilder的区别

String.StringBuffer.StringBuilder的区别 理论(这几个东西的区别是啥?)---先不说话我们先上代码,不管懂不懂,先照抄! package com.sandy; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import java.util.Iterator; /** * Created by alittlefish on 2017/8/17. */ pu