首页 > 代码库 > POJ_1200_Crazy Search
POJ_1200_Crazy Search
1. 题目描述
给一个长串,找出不重复的,长度为nc的字串数目。
2. 代码示例
1 /* 2 Source Code 3 4 Problem: 1200 User: robinho364 5 Memory: 40504K Time: 63MS 6 Language: G++ Result: Accepted 7 */ 8 #define _USE_MATH_DEFINES 9 10 #ifdef ONLINE_JUDGE 11 #define FINPUT(file) 0 12 #define FOUTPUT(file) 0 13 #else 14 #define FINPUT(file) freopen(file,"r",stdin) 15 #define FOUTPUT(file) freopen(file,"w",stdout) 16 #endif 17 18 #include <iostream> 19 #include <cstdio> 20 #include <cstring> 21 #include <cstdlib> 22 #include <cmath> 23 #include <ctime> 24 #include <set> 25 #include <stack> 26 #include <string> 27 #include <map> 28 #include <vector> 29 #include <queue> 30 #include <algorithm> 31 #include <functional> 32 33 typedef long long ll; 34 static const int N = 16000010; 35 static const int M = 20; 36 static const int LEN = 100; 37 static const int MAX = 0x7fffffff; 38 static const int GMAX = 0x3f3f3f3f; 39 static const int MIN = ~MAX; 40 static const double EPS = 1e-7; 41 static const int BASE = 10000007; 42 static const int CH = 27; 43 char str[N]; 44 int hash[BASE]; 45 int char_to_num[257]; 46 47 bool inline cmp(int i, int j, int n) 48 { 49 int res = strncmp(str + i, str + j, n); 50 if (res) { 51 return false; 52 } else { 53 return true; 54 } 55 } 56 57 void inline rabin_karp(int n, int nc, int len) 58 { 59 int seed = 0; 60 for(int i = 0;i<len;i++){ 61 if(char_to_num[str[i]] == 0){ 62 char_to_num[str[i]] = ++seed; 63 } 64 } 65 66 int t = 1; 67 68 for(int i = 0;i<n;i++) 69 t*=nc; 70 71 int ah = 0; 72 73 for(int i = 0;i<n;i++) 74 ah = (ah*nc + char_to_num[str[i]]) % BASE; 75 76 int ncount = 0; 77 for(int i = 0;i+n<=len;i++){ 78 if(!hash[ah]){ 79 hash[ah] = i + 1; 80 ncount++; 81 } else { 82 int res = ah; 83 while (hash[res] && !cmp(i, hash[res] - 1, n)) { 84 res = (res + 1) % BASE; 85 } 86 hash[res] = i + 1; 87 } 88 if(i+n<len){ 89 ah = (ah*nc + char_to_num[str[i+n]] - char_to_num[str[i]]*t)%BASE; 90 } 91 } 92 93 printf("%d\n", ncount); 94 } 95 96 int main() 97 { 98 FINPUT("in.txt"); 99 FOUTPUT("out.txt");100 101 int n, nc;102 while (scanf("%d %d", &n, &nc) != EOF) {103 scanf("%s", str);104 memset(char_to_num, 0, sizeof(char_to_num));105 memset(hash, false, sizeof(hash));106 rabin_karp(n, nc + 1, strlen(str));107 }108 109 return 0;110 }
1 /* 2 Source Code 3 4 Problem: 1200 User: robinho364 5 Memory: 17008K Time: 32MS 6 Language: G++ Result: Accepted 7 */ 8 #define _USE_MATH_DEFINES 9 10 #ifdef ONLINE_JUDGE11 #define FINPUT(file) 012 #define FOUTPUT(file) 013 #else14 #define FINPUT(file) freopen(file,"r",stdin)15 #define FOUTPUT(file) freopen(file,"w",stdout)16 #endif17 18 #include <iostream>19 #include <cstdio>20 #include <cstring>21 #include <cstdlib>22 #include <cmath>23 #include <ctime>24 #include <set>25 #include <stack>26 #include <string>27 #include <map>28 #include <vector>29 #include <queue>30 #include <algorithm>31 #include <functional>32 33 typedef long long ll;34 static const int N = 16000010;35 static const int M = 20;36 static const int LEN = 100;37 static const int MAX = 0x7fffffff;38 static const int GMAX = 0x3f3f3f3f;39 static const int MIN = ~MAX;40 static const double EPS = 1e-7;41 static const int BASE = 6000011;42 static const int CH = 27;43 char str[N];44 bool hash[N];45 int char_to_num[257];46 47 void inline rabin_karp(int n, int nc, int len)48 {49 int seed = 0;50 for(int i = 0;i<len;i++){51 if(char_to_num[str[i]] == 0){52 char_to_num[str[i]] = ++seed;53 }54 }55 56 int t = 1;57 58 for(int i = 0;i<n;i++)59 t*=nc;60 61 int ah = 0;62 63 for(int i = 0;i<n;i++)64 ah = ah*nc + char_to_num[str[i]];65 66 int ncount = 0;67 for(int i = 0;i+n<=len;i++){68 if(hash[ah] == false){69 hash[ah] = true;70 ncount++;71 }72 if(i+n<len){73 ah = ah*nc + char_to_num[str[i+n]] - char_to_num[str[i]]*t;74 }75 }76 77 printf("%d\n", ncount);78 }79 80 int main()81 {82 FINPUT("in.txt");83 FOUTPUT("out.txt");84 85 int n, nc;86 while (scanf("%d %d", &n, &nc) != EOF) {87 scanf("%s", str);88 memset(char_to_num, 0, sizeof(char_to_num));89 memset(hash, false, sizeof(hash));90 rabin_karp(n, nc + 1, strlen(str));91 }92 93 return 0;94 }
3. 备注
题目中还给了所有不同的字符总数,因此很明显是用Hash来做。
如果直接用rabin-carp的话需要开很大的数组,加上Hash比较就不用了;
Hash的时候需要注意Hash数组的大小,也不能太小,可能会超时。
rabin-carp基础:
1. 取基数(一般为字符总数k+1,看成k+1进制数)。
2. 计算Hash值,左边权值最高,右边权值最低。类似于计算机中的大端法表示,最重要的部分在低地址。
3. 滚动Hash,减去最左边的值(权值最高的那位),加上下一个数(权值最低的那位),其他部分每位都乘以权值。
POJ_1200_Crazy Search
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。