【HDU - 5672】String(尺取法)
題干:
There is a string?SS.SS?only contain lower case English character.(10≤length(S)≤1,000,000)(10≤length(S)≤1,000,000)?
How many substrings there are that contain at least?k(1≤k≤26)k(1≤k≤26)?distinct characters?
Input
There are multiple test cases. The first line of input contains an integer?T(1≤T≤10)T(1≤T≤10)?indicating the number of test cases. For each test case:?
The first line contains string?SS.?
The second line contains a integer?k(1≤k≤26)k(1≤k≤26).
Output
For each test case, output the number of substrings that contain at least?kk?dictinct characters.
Sample Input
2 abcabcabca 4 abcabcabcabc 3Sample Output
0 55題目大意:
? ?問有多少個? 含有不少于k種字符的 子字符串。
解題報告:
? ?尺取法,但是我是以右端點為一個記錄,即 表示以第s[r]個字符為結(jié)尾,有多少個字符串滿足。這種方法需要處理cnt>k的情況。
還有一種方法,每次統(tǒng)計以s[l]為起始的,有多少個子字符串滿足,這種不需要考慮cnt>k的情況。
AC代碼:
#include<bits/stdc++.h> #define ll long long using namespace std; const int MAX = 1e6 +5; char s[MAX]; int l,r,cnt,k,num[30]; ll ans; int main() {int t;cin>>t;while(t--) {scanf("%s",s+1);scanf("%d",&k);memset(num,0,sizeof num);int len = strlen(s+1);l = 1,r = 1;cnt = 0;ans = 0;while(l<=len && r <=len) {if(num[s[r] - 'a'] == 0) {cnt++;}num[s[r] - 'a']++;while(cnt > k) {while(num[s[l]-'a'] >=1) {num[s[l]-'a']--;if(num[s[l]-'a']==0) cnt--;l++;if(cnt == k) break;}}if(cnt == k) {while(num[s[l]-'a'] > 1) num[s[l]-'a']--,l++;ans += l;}r++;}printf("%lld\n",ans);}return 0 ;} /* 1 aabcc 3 */錯誤代碼:
#include<bits/stdc++.h> #define ll long long using namespace std; const int MAX = 1e6 +5; char s[MAX]; int l,r,cnt,k,num[30]; ll ans; int main() {int t;cin>>t;while(t--) {scanf("%s",s+1);scanf("%d",&k);memset(num,0,sizeof num);int len = strlen(s+1);l = 1,r = 1;cnt = 0;ans = 0;while(l<=len && r <=len) {if(num[s[r] - 'a'] == 0) {cnt++;}num[s[r] - 'a']++;if(cnt == k) {while(num[s[l]-'a'] > 1) num[s[l]-'a']--,l++;ans += l;}r++;}printf("%lld\n",ans);}return 0 ;}測試樣例:
1
abc
2
應(yīng)該輸出3,但是輸出了1。
?
AC代碼2:(左端點的)
#include<cstdio> #include<cstring> using namespace std; char s[1000200]; int vis[30]; int main() {int t,k;scanf("%d", &t);while (t--){scanf("%s%d", s,&k);int len = strlen(s), sum = 0, r = -1;long long ans = 0;memset(vis, 0, sizeof(vis));for (int i = 0; i < len; i++){while (sum < k&&r+2<=len){r++;vis[s[r] - 'a']++;if (vis[s[r] - 'a'] == 1)sum++;}if (sum==k)ans += len - r;vis[s[i] - 'a']--;if (vis[s[i] - 'a'] == 0)sum--;}printf("%I64d\n", ans);} }?
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的【HDU - 5672】String(尺取法)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是储蓄国债?储蓄国债与其他理财相比有
- 下一篇: 【CF#931.B】World Cup