hdu 4821 字符串hash + map判重
来源:互联网 发布:上海师范大学网络课程 编辑:程序博客网 时间:2024/06/06 09:54
String
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3458 Accepted Submission(s): 1050
Problem Description
Given a string S and two integers L and M, we consider a substring of S as “recoverable” if and only if
(i) It is of length M*L;
(ii) It can be constructed by concatenating M “diversified” substrings of S, where each of these substrings has length L; two strings are considered as “diversified” if they don’t have the same character for every position.
Two substrings of S are considered as “different” if they are cut from different part of S. For example, string "aa" has 3 different substrings "aa", "a" and "a".
Your task is to calculate the number of different “recoverable” substrings of S.
(i) It is of length M*L;
(ii) It can be constructed by concatenating M “diversified” substrings of S, where each of these substrings has length L; two strings are considered as “diversified” if they don’t have the same character for every position.
Two substrings of S are considered as “different” if they are cut from different part of S. For example, string "aa" has 3 different substrings "aa", "a" and "a".
Your task is to calculate the number of different “recoverable” substrings of S.
Input
The input contains multiple test cases, proceeding to the End of File.
The first line of each test case has two space-separated integers M and L.
The second ine of each test case has a string S, which consists of only lowercase letters.
The length of S is not larger than 10^5, and 1 ≤ M * L ≤ the length of S.
The first line of each test case has two space-separated integers M and L.
The second ine of each test case has a string S, which consists of only lowercase letters.
The length of S is not larger than 10^5, and 1 ≤ M * L ≤ the length of S.
Output
For each test case, output the answer in a single line.
Sample Input
3 3abcabcbcaabc
Sample Output
2
Source
2013 Asia Regional Changchun
题意:给定一个字符串,把它分为多个长度为M*L的子串,对于每个子串要求再把它分为M个长度为L的小子串,对于这M个长度为L的小子串要求任意两个都不相同。问能够分成多少个这样的长度为M*L的子串。
思路:
第一次写的时候,用hash暴力从每个开始点判断一个长度为M*L的子串是否符合条件。但是超时了,时间复杂度为O(n^2)。
后来看了别人的思路,发现可以将总的字符串分为L个序列,对于每个序列,如果已经判断了一个,那么只要将判断过的子串去掉开头的L个字符,然后在子串的后面再加上L个字符,就是一个新的子串,这样实际上对于每个序列里,长度为L的字符串都只计算了一遍。对于暴力的话,要计算多次,浪费了时间。(可能有点绕)
代码:
#include<algorithm>#include<iostream>#include<cstdio>#include<string.h>#include<cmath>#include<map>using namespace std;typedef unsigned long long ull;const int N = 1e5+5;const int X = 163;ull hhash[N], p[N];char str[N];int m, l;map<ull, int> Map;void inIt() {p[0] = 1;for(int i = 1; i <= N- 5; i++)p[i] = p[i-1] * X;}ull get(int l, int r, ull g[]) {return g[r] - g[l-1]*p[r-l+1];}int main() {int length, flag;int number;ull sum, temp;int count, i ,j;inIt();while(scanf("%d%d", &m, &l) != EOF) {scanf("%s", str);length = strlen(str);number = 0;hhash[0] = 0;for(i = 1; i <= length; i++)hhash[i] = hhash[i-1]*X + (str[i-1]- 'a');for(i = 1; i <= l && i <= length - m*l; i++) { //既然分为了L个序列,为什么还要加上 Map.clear();//i<=length-m*l这个条件呢?原因很简单,有可能不够L个序列 for(j = i; j < i+m*l-1; j+=l) {//假设有L=3个序列 ,m=4,字符串长度为12, temp = get(j, j+l-1, hhash);//其实只有该字符串本身可能满足条件,但是这里却要 Map[temp]++;//循环3次,多了,所以要加上上面的条件。 } if(Map.size() == m)number++;int head;for(; j+l-1 <= length; j+= l) {head = j - m*l; //去掉开头的L个字符。 temp = get(head, head+l-1, hhash);Map[temp]--;if(Map[temp] == 0) {Map.erase(temp);}temp = get(j, j+l-1, hhash);//加上后面的L个字符。 Map[temp]++;if(Map.size() == m)number++;}}printf("%d\n", number);}}
阅读全文
0 0
- hdu 4821 字符串hash + map判重
- hdu 4821 hash+map判重
- hdu 4821 字符串hash+map判重 String (长春市赛区I题)
- HDU 1067 HASH判重BFS
- hdu 1067(bfs+hash判重)
- hdu 4821 String(字符串hash+map)
- HDU 2072 字符串处理(判重)
- 字符串hash判重/trie树判重(poj3007)
- hdu 4090 bfs+dfs+状态压缩+hash判重
- HDU ACM 1067 Gap->BFS+HASH判重
- hdu 5012 bfs --- 慎用STL 比如MAP判重
- HDU 4821 String 字符串hash map的妙用
- HDU 4821 字符串hash
- hdu 4821(字符串hash)
- 面试:字符串:字符串判重
- 面试:字符串:字符串判重
- POJ Holedox Moving BFS hash判重
- poj 3131 双向搜索+hash判重
- 头条页面
- Socket请求分析
- Binding应用(一)
- c++构建正态分布的随机数
- C语言排序算法汇总
- hdu 4821 字符串hash + map判重
- “非常量引用的初始值必须为左值”问题
- fastsocket试用
- 简单的跑马灯效果
- Eclipse启动加载自定义jdk
- 平面图欧拉公式的精彩证明
- layer 获取页面层(type:1)元素
- JAVA学习线程的初步理解
- KMP 算法,背包问题