BestCoder Round #81 (div.2)C HDOJ5672 String(双指针法)

本文介绍了一种算法,用于解决给定字符串中包含至少k个不同字符的子串数量计算问题。通过移动指针技术和哈希映射,有效地解决了这一挑战。

String

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 813    Accepted Submission(s): 258


Problem Description
There is a string  S . S  only contain lower case English character. (10length(S)1,000,000)
How many substrings there are that contain at least  k(1k26)  distinct characters?
 

Input
There are multiple test cases. The first line of input contains an integer  T(1T10)  indicating the number of test cases. For each test case:

The first line contains string  S .
The second line contains a integer  k(1k26) .
 

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


题目链接:点击打开链接

给出一个字符串和需要的字符串长度, 输出复合要求子串个数.

头尾指针移动, 等于需要字符串长度时计算尾指针距离末尾长度, 得到子串个数累加.

AC代码:

#include "iostream"
#include "cstdio"
#include "cstring"
#include "algorithm"
#include "queue"
#include "stack"
#include "cmath"
#include "utility"
#include "map"
#include "set"
#include "vector"
#include "list"
#include "string"
#include "cstdlib"
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
#define st first
#define nd second
#define exp 1e-8
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
const int MOD = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const int MAXN = 1e6 + 6;
int t, k, len, st, ed, cnt, num[30];
char s[MAXN];
std::map<char, int> mp;
int main(int argc, char const *argv[])
{
    scanf("%d", &t);
    while(t--) {
        memset(num, 0, sizeof(num));
        scanf("%s%d", s, &k);
        len = strlen(s), st = 0, ed = 0, cnt = 0;
        ll ans = 0;
        while(st < len) {
            if(st) {
                num[s[st - 1] - 'a']--;
                if(!num[s[st - 1] - 'a']) cnt--;
            }
            while(cnt < k && ed < len) {
                if(!num[s[ed] - 'a']) cnt++;
                num[s[ed] - 'a']++;
                ed++;
            }
            if(cnt >= k) ans += len - ed + 1;
            st++;
        }
        printf("%lld\n", ans);
    }
    return 0;
}


### HDOJ 2065 C语言解题思路及代码实现 #### 题目描述 HDOJ 2065 是一道关于字符串处理的经典题目。给定一段英文文本,要求将其中的单词顺序反转并保持标点符号位置不变。 #### 解题思路 为了高效解决这个问题,可以采用双端队列(deque)来辅助处理。具体来说: - 使用两个指针分别指向当前读取的位置和待输出的位置。 - 当遇到字母时将其压入栈中暂存。 - 若碰到非字母字符,则直接输出该字符,并依次弹出栈内的所有字母直至为空[^1]。 这种方法不仅逻辑清晰简单易于理解,同时也保证了较高的执行效率。 #### 代码实现 以下是基于上述思路编写的C语言版本解决方案: ```c #include <stdio.h> #include <ctype.h> #define MAX_LEN 1000 // 定义最大长度常量 int main() { char str[MAX_LEN], stack[MAX_LEN]; int top = -1; fgets(str, sizeof(str), stdin); for(int i = 0; str[i]; ++i){ if(isalpha(str[i])){ stack[++top] = str[i]; // 字母入栈 }else{ while(top != -1){ // 输出栈内所有字母 putchar(stack[top--]); } putchar(str[i]); // 输出非字母字符 } } while(top != -1){ // 处理最后一串连续字母 putchar(stack[top--]); } return 0; } ``` 此段代码通过`fgets()`函数获取输入字符串,并利用标准库中的`isalpha()`函数判断字符是否为英文字母。对于每一个非空白字符,如果是字母则加入到临时保存区域(即stack数组),如果不是字母而是其他符号,则先打印之前累积的所有字母再打印这个特殊符号。最后还需额外检查一次堆栈里是否有剩余未被处理过的字母序列[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值