杭电4333扩展kmp
来源:互联网 发布:js 获取cookie的值 编辑:程序博客网 时间:2024/06/06 10:44
Revolving Digits
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 1618 Accepted Submission(s): 467
Problem Description
One day Silence is interested in revolving the digits of a positive integer. In the revolving operation, he can put several last digits to the front of the integer. Of course, he can put all the digits to the front, so he will get the integer itself. For example, he can change 123 into 312, 231 and 123. Now he wanted to know how many different integers he can get that is less than the original integer, how many different integers he can get that is equal to the original integer and how many different integers he can get that is greater than the original integer. We will ensure that the original integer is positive and it has no leading zeros, but if we get an integer with some leading zeros by revolving the digits, we will regard the new integer as it has no leading zeros. For example, if the original integer is 104, we can get 410, 41 and 104.
Input
The first line of the input contains an integer T (1<=T<=50) which means the number of test cases.
For each test cases, there is only one line that is the original integer N. we will ensure that N is an positive integer without leading zeros and N is less than 10^100000.
For each test cases, there is only one line that is the original integer N. we will ensure that N is an positive integer without leading zeros and N is less than 10^100000.
Output
For each test case, please output a line which is "Case X: L E G", X means the number of the test case. And L means the number of integers is less than N that we can get by revolving digits. E means the number of integers is equal to N. G means the number of integers is greater than N.
Sample Input
1341
Sample Output
Case 1: 1 1 1
Source
2012 Multi-University Training Contest 4
几天没写博客了。。看的kmp想吐血了
这个题目纠结了两天了,开始看人家的代码看不懂。。
后来自己写了一个又超时,我发现很多求kmp的next数组第一个都是-1,我偏偏看了是0的代码(感觉容易理解),
这题主要求出最短循环结的长度就好办了,然后再求扩展kmp的next数组的值,最后比较。。
先附上超时代吗:
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int MAXN = 10^100000*2;char str[MAXN];int next[MAXN];int nnext[MAXN];void makeNext(){ int q,i; nnext[0]=0; for(q=0,i=1;i<strlen(str);++i) { while(q>0 && str[i]!=str[q]) { q=nnext[q-1]; } if(str[i]==str[q]) { ++q; } nnext[i]=q; }}/*void SetPrefix(const char *Pattern, int prefix[]){ int len=strlen(Pattern);//模式字符串长度。 prefix[0]=0; for(int i=1; i<len; i++) { int k=prefix[i-1]; //不断递归判断是否存在子对称,k=0说明不再有子对称,Pattern[i] != Pattern[k]说明虽然对称,但是对称后面的值和当前的字符值不相等,所以继续递推 while( Pattern[i] != Pattern[k] && k!=0 ) k=prefix[k-1]; //继续递归 if( Pattern[i] == Pattern[k])//找到了这个子对称,或者是直接继承了前面的对称性,这两种都在前面的基础上++ prefix[i]=k+1; else prefix[i]=0; //如果遍历了所有子对称都无效,说明这个新字符不具有对称性,清0 }}*/void getnext(char *s,int *n){ int len = strlen(s),a = 0; n[0] = len; while(a<len-1 && s[a] == s[a+1]) a++; n[1] = a; a = 1; for(int k = 2; k<len; k++) { int p = a+n[a]-1,l = n[k-a]; if((k-1)+l>=p) { int j = (p-k+1)>0?(p-k+1):0; while(k+j<len && s[k+j] == s[j]) j++; n[k] = j; a = k; } else n[k] = l; }}int main(){ int n; cin >> n; getchar(); for(int m = 1; m<=n; m++) { gets(str); int len = strlen(str); for(int j = 0; j<len; j++) { str[len+j] = str[j]; } str[2*len] = '\0'; getnext(str,next); int l = 0,e = 0,g = 0; makeNext(); // SetPrefix(str,nnext); int k=0,p; p=len-nnext[len-1]; if(len%p==0) { // printf("if\n"); k=p; } else {//printf("else\n"); k=len; } for(int i = 0; i<k; i++) { if(next[i] >= len) e++; else if(next[i] > 0 && next[i]<len) { if(str[i+next[i]]>str[next[i]]) g++; else l++; } else if(next[i] == 0) { if(str[i]>str[0]) g++; else l++; } } printf("Case %d: %d %d %d\n",m,l,e,g); } return 0;}
然后是未超时的代码,第一个是0的:
#include<iostream>#include<cstdio>#include<cstring>using namespace std;const int MAXN = 10^100000*2;char str[MAXN];int next[MAXN];int nnext[MAXN];/*void makeNext(){ int q,i; nnext[0]=0; for(q=0,i=1;i<strlen(str);++i) { while(q>0 && str[i]!=str[q]) { q=nnext[q-1]; } if(str[i]==str[q]) { ++q; } nnext[i]=q; }}*/void SetPrefix(const char *Pattern, int prefix[]){ int len=strlen(Pattern);//模式字符串长度。 prefix[0]=0; for(int i=1; i<len; i++) { int k=prefix[i-1]; //不断递归判断是否存在子对称,k=0说明不再有子对称,Pattern[i] != Pattern[k]说明虽然对称,但是对称后面的值和当前的字符值不相等,所以继续递推 while( Pattern[i] != Pattern[k] && k!=0 ) k=prefix[k-1]; //继续递归 if( Pattern[i] == Pattern[k])//找到了这个子对称,或者是直接继承了前面的对称性,这两种都在前面的基础上++ prefix[i]=k+1; else prefix[i]=0; //如果遍历了所有子对称都无效,说明这个新字符不具有对称性,清0 }}void getnext(char *s,int *n){ int len = strlen(s),a = 0; n[0] = len; while(a<len-1 && s[a] == s[a+1]) a++; n[1] = a; a = 1; for(int k = 2; k<len; k++) { int p = a+n[a]-1,l = n[k-a]; if((k-1)+l>=p) { int j = (p-k+1)>0?(p-k+1):0; while(k+j<len && s[k+j] == s[j]) j++; n[k] = j; a = k; } else n[k] = l; }}int main(){ int n; cin >> n; getchar(); for(int m = 1; m<=n; m++) { gets(str); int len = strlen(str); for(int j = 0; j<len; j++) { str[len+j] = str[j]; } str[2*len] = '\0'; getnext(str,next); int l = 0,e = 0,g = 0; // makeNext(); SetPrefix(str,nnext); int k=0,p; p=len-nnext[len-1]; if(len%p==0) { // printf("if\n"); k=p; } else {//printf("else\n"); k=len; } for(int i = 0; i<k; i++) { if(next[i] >= len) e++; else if(next[i] > 0 && next[i]<len) { if(str[i+next[i]]>str[next[i]]) g++; else l++; } else if(next[i] == 0) { if(str[i]>str[0]) g++; else l++; } } printf("Case %d: %d %d %d\n",m,l,e,g); } return 0;}
0 0
- 杭电4333扩展kmp
- 杭电3613扩展kmp
- hdu 4333 kmp+扩展kmp
- 杭电4300kmp
- hdu 4333 扩展kmp
- hdu 4333 扩展KMP
- hdu 4333(扩展KMP)
- hdu 4333 扩展KMP
- HDU 4333 扩展KMP
- hdu 4333(扩展KMP)
- 杭电 KMP算法题目
- 杭电 1711 KMP算法
- 杭电 1686 Oulipo (kmp)
- HDOJ 4333 Revolving Digits(KMP+扩展KMP)
- HDU 4333:Revolving Digits KMP+扩展KMP
- 扩展KMP
- 扩展KMP
- 扩展KMP
- 1015. Reversible Primes (20)
- poj3301(三分-坐标旋转)
- android音频视频播放器
- mahout0.8 分布式运行20newsgroup(dataguru mahout 第一周作业)
- 第3章 Android的事件处理
- 杭电4333扩展kmp
- [CrackCode] 2.2 Find the nth to last element of a singly linked list
- Android网络程序出现HttpHostConnectException及NetworkOnMainThreadException解决方法
- Integer Inquiry
- linux man中文帮助
- Google Java编程风格指南
- ubuntu server 语言设置为英文
- workqueue原理和分析
- [CrackCode] 2.3 Delete a node in the middle of a single linked list