poj2406 Power Strings
2016-07-28 19:19
309 查看
Power Strings
Description
Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the
empty string) and a^(n+1) = a*(a^n).
Input
Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.
Output
For each s you should print the largest n such that s = a^n for some string a.
Sample Input
Sample Output
Hint
This problem has huge input, use scanf instead of cin to avoid time limit exceed.
通过分析,可以发现,对于非循环串,答案一定为1,对于循环串,答案=字符串长度÷最小循环节长度
第一个技巧是最小循环节长度的寻找,通过分析不难证明,最小循环节长度=字符串总长-next[最后一个字符],其中next的含义和求法详见kmp算法的介绍(link:)
第二个技巧是判断一个字符串是不是循环串,下图中,用黑色的表示整个字符串,不同颜色的分别表示对应位置的子串。先假设原串是循环串,绿色的是循环节,长度为l,那么首先一定满足len%l==0,其中len是原串长度。根据假设图中两个绿色的部分相等,所以红色和黄色的部分也相等。好,现在我们去掉之前所有的假设,反过来看看能推出什么。当满足len%l==0时,如果红色与黄色部分相等,则一定有两个绿色部分相等,又因为上边的蓝色部分=下边的绿色部分=下边的蓝色部分=上边的粉色部分=下边的粉色部分=······=最后绿色部分下面对应的部分,所以整个串就是以绿色部分为循环节的循环串。
综合上述两个技巧,即可轻松AC
****真是费劲。。。写个题解比写代码用的时间还多
Time Limit: 3000MS | Memory Limit: 65536K | |
Total Submissions: 43193 | Accepted: 18036 |
Given two strings a and b we define a*b to be their concatenation. For example, if a = "abc" and b = "def" then a*b = "abcdef". If we think of concatenation as multiplication, exponentiation by a non-negative integer is defined in the normal way: a^0 = "" (the
empty string) and a^(n+1) = a*(a^n).
Input
Each test case is a line of input representing s, a string of printable characters. The length of s will be at least 1 and will not exceed 1 million characters. A line containing a period follows the last test case.
Output
For each s you should print the largest n such that s = a^n for some string a.
Sample Input
abcd aaaa ababab .
Sample Output
1 4 3
Hint
This problem has huge input, use scanf instead of cin to avoid time limit exceed.
Analysis
这道题目用到好多技巧。通过分析,可以发现,对于非循环串,答案一定为1,对于循环串,答案=字符串长度÷最小循环节长度
第一个技巧是最小循环节长度的寻找,通过分析不难证明,最小循环节长度=字符串总长-next[最后一个字符],其中next的含义和求法详见kmp算法的介绍(link:)
第二个技巧是判断一个字符串是不是循环串,下图中,用黑色的表示整个字符串,不同颜色的分别表示对应位置的子串。先假设原串是循环串,绿色的是循环节,长度为l,那么首先一定满足len%l==0,其中len是原串长度。根据假设图中两个绿色的部分相等,所以红色和黄色的部分也相等。好,现在我们去掉之前所有的假设,反过来看看能推出什么。当满足len%l==0时,如果红色与黄色部分相等,则一定有两个绿色部分相等,又因为上边的蓝色部分=下边的绿色部分=下边的蓝色部分=上边的粉色部分=下边的粉色部分=······=最后绿色部分下面对应的部分,所以整个串就是以绿色部分为循环节的循环串。
综合上述两个技巧,即可轻松AC
****真是费劲。。。写个题解比写代码用的时间还多
CODE
//poj2406 Power Strings kmp简单应用 #include <cstdio> #include <cstring> #define maxlen 1000010 using namespace std; char s[maxlen]; int next[maxlen], len; bool judge(int l) { int i; if(len%l)return false; for(i=1;i+l<=len;i++) if(s[i]!=s[i+l])return false; return true; } int main() { int i, j, l; s[0]=48; while(scanf("%s",s+1),s[1]!='.') { len=strlen(s)-1; for(i=2,j=0;i<=len;i++) { for(;j&&s[j+1]!=s[i];j=next[j]); if(s[j+1]==s[i])j++; next[i]=j; } if(judge(len-next[len])) printf("%d\n",len/(len-next[len])); else printf("1\n"); } return 0; }
相关文章推荐
- 对CAN驱动中的NAPI机制的理解
- POJ 3176 Cow Bowling (水题DP)
- 快排的递归和非递归实现
- 进制转换
- 设计模式之代理模式
- AABB和OBB包围盒简介
- Android内容提供者Provider
- 探寻C++最快的读取文件的方案 C++ IO优化
- ftp操作记录
- 将mybatis-generator封装成Maven插件
- HDU 5773 DP LIS变形
- 算法导论——钢条切割问题
- ajaxFileUpload带参数提交(亲测可用)
- <a>链接打开新窗口
- IronWasp Web应用程序漏洞扫描
- 安卓开发过程中遇到问题总结二
- 对Socket CAN的理解(5)——【Socket CAN控制器的初始化过程】
- 【腾讯Bugly干货分享】一步一步实现Android的MVP框架
- Android 面试题大全
- 根据文字设置label的size