當前位置:
首頁 >
hdu5056(找相同字母不出现k次的子串个数)
發布時間:2025/6/17
35
豆豆
生活随笔
收集整理的這篇文章主要介紹了
hdu5056(找相同字母不出现k次的子串个数)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題意:
? ? ?給你一個字符串,然后問你這個字符串里面有多少個滿足要求的子串,要求是每個子串相同字母出現的次數不能超過k。
思路:
? ? ?這種題目做著比較有意思,而且不是很難(但自己還是嘚瑟,wa了好幾次),這個題目的關鍵就是時間問題,對于每一個字母,我們只要加上以他為結尾的滿足要求的子串個數就行了,假如前面的字母出現個數都沒有超過k,那么當前的可以增加的和就是之前所有的字母個數,如果當前的字母個數出現超過k了,那么就得更新起點now(這個起點就是自己作為標記可行的最前位置),ans += 當前到now的字母的個數,具體的細節看下面代碼,我寫個核心的部分。
int now = 0;
for(int i = 0 ;i < n ;i ++)
{
? ? if(++mark[str[i]] > k)
? ? {
? ? ? ?int nowid = now;
? ? ? ?while(1)//這個別忘記了,一開始忘記了wa了好幾次,挪動當前滿足串的范圍的時 ? ? ? ? { ? ? ? //候記得挪動出去的部分的字母出現次數減出去。
? ? ? ? ? mark[str[nowid]] --;
? ? ? ? ? if(str[nowid] == str[i]) break;
? ? ? ? ? nowid ++;
? ? ? ?}
? ? ? ?now = nowid;
? ? ?}
? ? ?Ans += (i+1 - now);
? ? ?給你一個字符串,然后問你這個字符串里面有多少個滿足要求的子串,要求是每個子串相同字母出現的次數不能超過k。
思路:
? ? ?這種題目做著比較有意思,而且不是很難(但自己還是嘚瑟,wa了好幾次),這個題目的關鍵就是時間問題,對于每一個字母,我們只要加上以他為結尾的滿足要求的子串個數就行了,假如前面的字母出現個數都沒有超過k,那么當前的可以增加的和就是之前所有的字母個數,如果當前的字母個數出現超過k了,那么就得更新起點now(這個起點就是自己作為標記可行的最前位置),ans += 當前到now的字母的個數,具體的細節看下面代碼,我寫個核心的部分。
int mark[] 表示的是當前可滿足的區間中每個字母出現的次數
int now 表示的是當前可滿足區間的最前端的下標int now = 0;
for(int i = 0 ;i < n ;i ++)
{
? ? if(++mark[str[i]] > k)
? ? {
? ? ? ?int nowid = now;
? ? ? ?while(1)//這個別忘記了,一開始忘記了wa了好幾次,挪動當前滿足串的范圍的時 ? ? ? ? { ? ? ? //候記得挪動出去的部分的字母出現次數減出去。
? ? ? ? ? mark[str[nowid]] --;
? ? ? ? ? if(str[nowid] == str[i]) break;
? ? ? ? ? nowid ++;
? ? ? ?}
? ? ? ?now = nowid;
? ? ?}
? ? ?Ans += (i+1 - now);
}
#include<stdio.h> #include<string.h> char str[110000]; int mark[30];int main () {int n ,t ,k;__int64 Ans ,i ,now;scanf("%d" ,&t);while(t--){scanf("%s" ,str);scanf("%d" ,&k);n = strlen(str);Ans = now = 0;memset(mark ,0 ,sizeof(mark));for(i = 0 ;i < n ;i ++){if(++mark[str[i]-'a'] > k){int nowi = now;while(1){mark[str[nowi]-'a'] --;if(str[nowi] == str[i]) break;nowi ++;}now = nowi + 1;}Ans += (i - now + 1);}printf("%I64d\n" ,Ans);}return 0; }
總結
以上是生活随笔為你收集整理的hdu5056(找相同字母不出现k次的子串个数)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: POJ 3613 快速幂+Floyd变形
- 下一篇: hdu1561 树形dp