kuangbin 專題二十三:二分 尺取 單調棧佇列 String
題目連線:
傳送門
#include<iostream>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N = 30;
const int M = 1000010;
int t, k, cnt[N];
char str[M];
int main() {
scanf("%d", &t);
while(t--) {
//輸入資料
scanf("%s", str);
scanf("%d", &k);
//初始化資料
memset(cnt, 0, sizeof cnt);
int n = strlen(str), f = 0;
ll ans = 0;
//尺取
for(int i = 0, j = 0; i < n; i++) {
//判斷當前尺子上是否存在k個不同的字元
while(j < n && f < k) {
//當前字元未出現過則f++
if(cnt[str[j] - 'a'] == 0) f++;
cnt[str[j] - 'a']++;
j++;
}
//如果f的個數符合要求
if(f == k) {
ans += n - j + 1;
}
//尺頭移出時數量要減一
cnt[str[i] - 'a']--;
//若該字元在尺子中再不出現則f--
if(cnt[str[i] - 'a'] == 0) f--;
}
printf("%lld\n", ans);
}
return 0;
}
這道題可以用尺取法來做
接下來講講尺取的方法:
首先設定幾個變數,f代表當前尺子上的不同類字元的個數,cnt陣列記錄當某字元出現過多少次,
然後講講思路:尺子頭尾都指向第一個字元,每次將尺尾往後移動,每次移動時判斷當前,當前尺尾的字母在尺子中是否出現過,如果未出現則讓 f 的數量加一,同時當前字元在尺子上出現的數量要加一,尺尾往後移,直到 f 的數量等於要求的k為止。此時前一段滿足,則後面的字元加入該串中也能形成符合條件的串,因此ans += n - j + 1。當記錄完後,把尺頭往前,往前移動時,要把對應的字元尺子中刪去,即尺頭對應的字元的數量要減一。同時如果這個尺子上再沒有同種字元的話,就要讓 f 減一。以此類推。
最後注意ans要開long long
相關文章
- 單調棧/單調佇列佇列
- 單調棧 和 單調佇列佇列
- 單調棧和單調佇列佇列
- 單調佇列佇列
- 單調佇列雙端佇列佇列
- 9. 題目:對佇列實現棧&用棧實現佇列佇列
- 棧,佇列,優先順序佇列簡單介面使用佇列
- 佇列,棧佇列
- 棧、佇列佇列
- 棧-佇列佇列
- 描述高頻題之佇列&棧佇列
- POJ 2823 單調佇列佇列
- hdu 3415 單調佇列佇列
- 佇列和棧佇列
- 棧和佇列佇列
- 多重揹包問題的單調佇列優化佇列優化
- HDU 3530 單調佇列佇列
- hdu 3401 單調佇列+DP佇列
- hdu 4122 單調佇列佇列
- 單調佇列最佳化 DP佇列
- 聯賽模擬測試18 A. 施工 單調佇列(棧)優化DP佇列優化
- 通過佇列實現棧OR通過棧實現佇列佇列
- 堆、棧以及佇列佇列
- java 棧與佇列Java佇列
- Java面試題:棧和佇列的實現Java面試題佇列
- POJ 3017 單調佇列dp佇列
- hdu4374單調佇列+dp佇列
- ABC372D ABC379F 題解 單調棧二分
- 佇列-單端佇列佇列
- POJ 2823Sliding Window(單調佇列水題)佇列
- 棧與佇列簡介佇列
- Chapter 2 棧和佇列APT佇列
- 6.13-棧與佇列佇列
- 用佇列實現棧佇列
- 用棧實現佇列佇列
- 專題五 並查集【Kuangbin】並查集
- 面試題之【用兩個棧實現佇列】面試題佇列
- 題目9:用兩個棧實現佇列佇列