您的位置:首页 > 其它

hdu_5672_Strings BestCoder Round #81 (div2)

2016-04-25 16:56 204 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5672

题目描述:

[align=left]Problem Description[/align]
There is a string S.S
only contain lower case English character.(10≤length(S)≤1,000,000)

How many substrings there are that contain at least
k(1≤k≤26)
distinct characters?
 

[align=left]Input[/align]
There are multiple test cases. The first line of input contains an integer
T(1≤T≤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≤k≤26).
 

[align=left]Output[/align]
For each test case, output the number of substrings that contain at least
k
dictinct characters.
 

[align=left]Sample Input[/align]

2
abcabcabca
4
abcabcabcabc
3

 

[align=left]Sample Output[/align]

0
55

题意:给一个字符串,求这样的子串的个数:子串中出现的不同字符个数大于等于k。

分析:刚开始想的是从i=0位置开始循环,寻找满足的j,使得s[i..j]满足条件,则它本身或者加上后面的字符都满足条件,那么数目就是len-j。累加即可。后来跟同学讨论后,发现好像又问题,如果有重复的子串怎么办?所以这个是错误的,然后提交后显示超时。然后就看了别人的解法,觉得太厉害了。采用双指针的思想,设置标记该字符是否出现在当前子串中。

超时代码:

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<stdlib.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;

#define pb(a) push_back(a)
#define mp(a,b) make_pair(a,b)
#define in(a) scanf("%d",&a)
#define out(a) printf("%d")
#define ll long long
#define FOR(i,l,r) for(int i=l;i<=r;i++)

const int N =1000006;
char s
;
ll ans;
int len;
int main()
{
int t,k;
scanf("%d",&t);
while(t--)
{
scanf("%s",s);
scanf("%d",&k);
len=strlen(s);
set<char>se;
int num;
ans=0;
for(int i=0;i<len;i++)
{
num=0;
se.clear();
for(int j=i;j<len;j++)
{
se.insert(s[j]);
if(se.size()>=k)
{
ans+=len-j;
break;
}
}
}
printf("%I64d\n",ans);
}
return 0;
}

代码:

#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<cmath>
#include<vector>
#include<cstdio>
#include<stdlib.h>
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;

#define pb(a) push_back(a)
#define mp(a,b) make_pair(a,b)
#define in(a) scanf("%d",&a)
#define out(a) printf("%d")
#define ll long long
#define FOR(i,l,r) for(int i=l;i<=r;i++)

const int N =1000006;
char s
;
int vis
;
ll ans;
int len;
int main()
{
int t,k;
scanf("%d",&t);
while(t--)
{
scanf("%s",s);
scanf("%d",&k);
len=strlen(s);
int num=0,i=0,j=0;
ans=0;
memset(vis,0,sizeof(vis));
for(i=0;i<len;i++)
{
while(true)
{
if(i+j>=len)break;
if(num>=k)break;
if(!vis[s[i+j]])
{
vis[s[i+j]]=1;
num++;
}
else vis[s[i+j]]++;
if(num>=k)break;
j++;
}
if(i+j>=len)break;
vis[s[i]]--;
if(num>=k)
ans+=len-i-j;
if(vis[s[i]]==0)
num--;
else j--;
}
printf("%I64d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: