题意:

给定一个字符串,然后将字符串最后的字母不断移动到字符串的首字母位置,需要求出在这个移动的过程中,生成的字符串比原串字典序大、相等、小的所有字符串个数。移动过程中,相同的字符串不重复计算。

思路:

由于是比较字典序,因此需要进行前缀比较。自然地想到要使用扩展kmp知识,我们这里先大概回忆一下扩展kmp知识。

next [ i ] : 模板串从 i 开始截取的子串与原串的最大前缀匹配长度

ex [ i ] : 匹配串从 i 开始截取的子串与模板串的最大前缀匹配长度

可以用线性时间求出这两个数组。

我们再来看这个题,就变成了一个水题。就是将这个串*2拼在一起,然后对于这个新串求一遍next数组即可。现在问题在于如何处理 “相同的字符串不重复计算” 这个问题,很自然地可以想到循环节。

令 cnt = 串S循环节在串S中出现了几次。

则对于这个串可能出现的所有串中,每个串出现的重复次数为cnt。因此最后的答案需要除以cnt。

总结:

扩展KMP就是用来计算前缀匹配长度的,应用于各类前缀匹配问题。

代码:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#define rep(i,a,b) for(int i = a; i <= b; i++)
using namespace std;
typedef long long ll;
const int INF = 2147483640;
const double eps = 1e-8;
const int N = 3*100000+100;   //字符串长度最大值char a[N];
int nxt[N]; //ex数组即为extend数组
//预处理计算next数组int get(char* tp)
{int nxtt[N];char s[N];memset(nxtt,0,sizeof nxtt);int l = strlen(tp);for(int i = l+1; i >= 1; i--) s[i] = tp[i-1];int j = 0;for(int i = 2;i <= l;i ++){while(j && s[j+1] != s[i])  j = nxtt[j];if(s[j+1] == s[i])  j ++;nxtt[i] = j;}return l-nxtt[l];
}void GETNEXT(char *str)
{int i=0,j,po,len=strlen(str);nxt[0]=len;//初始化next[0]while(str[i]==str[i+1]&&i+1<len)//计算next[1]i++;nxt[1]=i;po=1;//初始化po的位置for(i=2;i<len;i++){if(nxt[i-po]+i<nxt[po]+po)//第一种情况,可以直接得到next[i]的值nxt[i]=nxt[i-po];else//第二种情况,要继续匹配才能得到next[i]的值{j=nxt[po]+po-i;if(j<0)j=0;//如果i>po+next[po],则要从头开始匹配while(i+j<len&&str[j]==str[j+i])//计算next[i]j++;nxt[i]=j;po=i;//更新po的位置}}
}int main(int argc, char const *argv[])
{int T;scanf("%d",&T);rep(kk,1,T){scanf("%s",a);int len = strlen(a);int tp = get(a);int ans = len/tp;//    if(len % tp == 0) ans = len/tp;rep(i,len,2*len-1)a[i] = a[i-len];a[2*len] = '\0';GETNEXT(a);int c1 = 0,c2 = 0,c3 = 0;rep(i,0,len-1){if(a[i] == '0'){c1++;continue;}int tp = nxt[i];if(tp >= len) c2++;else{if(a[tp]-'0' < a[i+tp]-'0') c3++;else c1++;}}printf("Case %d: ",kk);printf("%d %d %d\n",c1/ans,c2/ans,c3/ans);}return 0;
}/*字符串从0开始编号next[i]: 模板串从i开始截取的子串与原串的最大前缀匹配长度ex[i]: 匹配串从i开始截取的子串与模板串的最大前缀匹配长度
*/

【扩展KMP】【HDU 4333】Revolving Digits相关推荐

  1. HDU - 4333 Revolving Digits(扩展KMP)

    题目链接:点击查看 题目大意:给出一个由 n 个数位组成的数字,现在可以通过将其不同的后缀移到前面来组成 n 个新的数字,现在要求出 n 个新数字进行去重后,有多少个新数字分别大于.等于.小于原数字 ...

  2. HDU - 4333 Revolving Digits 拓展KMP

    传送门:点击打开链接 一个长度为lent的串T最多可以构造出lent个数字,所以这道题目的难点在于如何快速的将构造出的数字和原数字进行比较. 将两个T串合并成一个大的S串,构造出的数字实际上就是S的每 ...

  3. hdu 4333 Revolving Digits

    http://acm.hdu.edu.cn/showproblem.php?pid=4333 对我来说这个题 太难了  看着标准程序敲的  伤不起呀 解析说是和KMP有关 不过已经变形的不成样子了 如 ...

  4. 【HDOJ】4333 Revolving Digits

    扩展KMP基础题目. 1 /* 4333 */ 2 #include <iostream> 3 #include <sstream> 4 #include <string ...

  5. 扩展KMP --- HDU 3613 Best Reward

    Best Reward Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=3613 Mean: 给你一个字符串,每个字符都有一个权 ...

  6. 一些扩展kmp的总结

    花了一天多时间学了下ex_kmp.... 可以看刘雅琼的ppt,讲的非常清楚: 下载地址:http://url.cn/Rvjxa9 ex_kmp可以在线性时间内求文本串的每个位置与模板串的最大公共前缀 ...

  7. 【hdu 4333】Revolving Digits

    [链接]http://acm.hdu.edu.cn/showproblem.php?pid=4333 [题意] 就是给你一个数字,然后把最后一个数字放到最前面去,经过几次变换后又回到原数字,问在这些数 ...

  8. HDU 3613 Best Reward 正反两次扩展KMP

    题目来源:HDU 3613 Best Reward 题意:每一个字母相应一个权值 将给你的字符串分成两部分 假设一部分是回文 这部分的值就是每一个字母的权值之和 求一种分法使得2部分的和最大 思路:考 ...

  9. HDU - 4300 Clairewd’s message(扩展KMP)

    题目链接:点击查看 题目大意:给出两个字符串 s 和 t ,字符串 s 代表着一种密码的映射,字符串 t 代表着一段密文+明文,题目保证密文是完整的,但明文只有一部分,现在问如何补全字符串 t ,使得 ...

  10. HDU - 6629 string matching(扩展KMP)

    题目链接:点击查看 题目大意:给出一个字符串 s 和一个暴力程序,用于求解 s 的每个后缀和原字符串的最长公共前缀,现在问一共需要执行多少次比较操作 题目分析:首先肯定不能暴力去模拟,时间复杂度n*n ...

最新文章

  1. 【MaxCompute】学习笔记常用查询sql
  2. BZOJ3230 相似子串 字符串 SA ST表
  3. android studio创建文件,如何在Android Studio中创建File Templates
  4. 剑指offer面试题65. 不用加减乘除做加法(位运算)
  5. 我是如何写作一本软件+哲学式的书籍的(上)
  6. 希望这篇文章对理解C#的对象模型有所帮助
  7. 《啊哈 C语言》读书笔记
  8. python的官网下载安装教程
  9. 计算机仿真塞曼效应实验报告,实验报告模板
  10. FFmpeg 视频裁剪
  11. js 实现大小写转换的方法
  12. 电脑知识 - bin文件夹是什么
  13. 怎样清理xp系统垃圾
  14. 物联网通信消息队列客户端-MQTT简介
  15. 图表美化设置圆角——《超级处理器》应用
  16. 中国哪些云主机比较靠谱?
  17. CentOS配置本地yum源/阿里云yum源/163yuan源
  18. 英文单词来生成语句java_Java代码编译过程简述
  19. 基于Labview平台的滚动轴承故障分析与噪声评价系统
  20. proteus仿真micropython_用Python让单片机“行动”起来——MicroPython实战入门篇

热门文章

  1. ConurrentHashMap和Hashtable的区别
  2. win7下對顯示器的電源的操作
  3. 交换机路由器常用命令
  4. linux 如何查看 块设备_理解Linux操作系统中的块设备
  5. java博客二级菜单的实现
  6. eclipse无法弹出控制台
  7. thinkphp上传图片并jquery预览
  8. 名校课程、计算机相关课程等网站连接
  9. java中查询redis中hash结构的值_阿里面试官:HashMap 熟悉吧?来聊聊 Redis 吧
  10. pyqt一个text实时显示另一个text的内容_python:基于tkinter打造的股票实时监控声音报警器! 自动监控,声音警报...