hdoj 5672 String (尺取法)
2016-04-26 21:25
148 查看
Description
There is a string $S$.$S$ only contain lower case English character.$(10 \leq length(S) \leq 1,000,000)$
How many substrings there are that contain at least $k(1 \leq k \leq 26)$ distinct characters?
Input
There are multiple test cases. The first line of input contains an integer $T (1\leq T\leq 10)$ indicating the number of test cases. For each test case:
The first line contains string $S$.
The second line contains a integer $k(1 \leq k \leq 26)$.
Output
For each test case, output the number of substrings that contain at least $k$ dictinct characters.
Sample Input
Sample Output
题目大意:
有一串字符串,然后给一个数字t,求包含t个不同的字符的字串个数。
解题思路:
尺取法,也叫双指针法,顾名思义,就是两个指针指向字串的起始和结束的地方。
解决此题是,因为要求包含不同单词的字串,如果{i ,j} 包含t个不同字符的个数,那个{i,k}(s(字串长度)>=k >= j)都包含t个不同字符的个数,设置一个数,表示最小右端点,然后依次更新最小左右端点,每次加上字串的个数,字串的个数就是字符串的长度减去最小右端点。
代码如下:
There is a string $S$.$S$ only contain lower case English character.$(10 \leq length(S) \leq 1,000,000)$
How many substrings there are that contain at least $k(1 \leq k \leq 26)$ distinct characters?
Input
There are multiple test cases. The first line of input contains an integer $T (1\leq T\leq 10)$ indicating the number of test cases. For each test case:
The first line contains string $S$.
The second line contains a integer $k(1 \leq k \leq 26)$.
Output
For each test case, output the number of substrings that contain at least $k$ dictinct characters.
Sample Input
2 abcabcabca 4 abcabcabcabc 3
Sample Output
0 55
题目大意:
有一串字符串,然后给一个数字t,求包含t个不同的字符的字串个数。
解题思路:
尺取法,也叫双指针法,顾名思义,就是两个指针指向字串的起始和结束的地方。
解决此题是,因为要求包含不同单词的字串,如果{i ,j} 包含t个不同字符的个数,那个{i,k}(s(字串长度)>=k >= j)都包含t个不同字符的个数,设置一个数,表示最小右端点,然后依次更新最小左右端点,每次加上字串的个数,字串的个数就是字符串的长度减去最小右端点。
代码如下:
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> #include<math.h> using namespace std; char s[1000010]; int main() { int a[27], t, k, i; long long sum; scanf("%d",&t); while(t--) { scanf("%s%d",s,&k); memset(a, 0, sizeof(a)); // 记录字串中各个字符的个数 int End, con; con = 0;End = -1;//End表示最小右端点 sum = 0; int len = strlen(s); for(i = 0; i < strlen(s); i++)//i就是最小左端点。 { while(con != k && (End < len)) { End++; if(End >= len) break; a[s[End] - 'a']++; if(a[s[End] - 'a'] == 1)//如果刚刚数过加入一个新的字符 con++; //字符个数加一。 } if(End >= len) break; sum =sum + (len - End);//每次加上子串的个数 a[s[i] - 'a']--;//最小左端点左移 if(a[s[i] - 'a'] == 0)//如果最小左端点代表的字符去掉之后字串字符的个数没有了,字符个数减一 con--; } printf("%lld\n",sum); } return 0; }
相关文章推荐
- 函数模块的应用以及理解
- 剑指offer(34):把数组排成最小的数
- C++第四次上机作业
- hdu 1115(多边形重心)
- View的事件分发机制一:事件分发概述
- HDOJ 5670 Machine
- 安卓驱动开发要干的那些事
- GSON实例详解
- 记kafka partition数据量过大导致不能正确重启
- Lowest Common Ancestor of a Binary Tree
- iframe自适应大小
- JavaScript Array(数组)
- Android Studio out of memory
- C++实现栈
- linux进程通信:消息队列
- 第6次作业
- 作业6 团队作业 阶段1
- 使用YCSB对HBase进行压测
- nyoj 16 矩形嵌套 (DAG上的动态规划)
- 如何打开.war文件