题意:已知26个字母的好坏,要求从给出的一个字符串中找出满足条件的子串数。【子串需满足:其存在的坏字母数最多只有k个】
思路:字符串哈希/trie树
WA代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double db;
typedef pair<int,int> pii;
typedef vector<int> vi;
#define de(x) cout << #x << "=" << x << endl
#define rep(i,a,b) for(int i=a;i<(b);++i)
#define all(x) (x).begin(),(x).end()
#define sz(x) (int)(x).size()
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define lb(x) (x&-(x))
#define MAX 26
#define MAXN 1503
char s[MAXN];
char isgood[26];
int badsum[MAXN];
int len,k;
char tmps[MAXN];
set<unsigned int> ss;
unsigned int BKDRHash(char *str)
{
unsigned int seed = 131; // 31 131 1313 13131 131313 etc..
unsigned int hash = 0;
while (*str)
{
hash = hash * seed + (*str++);
}
return (hash & 0x7FFFFFFF);
}
int main(){
scanf(" %s",s+1);
len=strlen(s+1);
scanf(" %s",isgood);
scanf("%d",&k);
rep(i,1,len+1)
{
badsum[i]=badsum[i-1];
if(isgood[s[i]-'a']=='0') badsum[i]++;
}
// rep(i,1,len+1) cout<<badsum[i];cout<<endl;
rep(i,1,len+1) rep(j,i,len+1)
{
if(badsum[j]-badsum[i-1]<=k)
{
strncpy(tmps,s+i,j-i+1);
tmps[j-i+1]='\0';
//hash之后看set中有没有 有就加入
unsigned int hs=BKDRHash(tmps);
if(ss.find(hs)==ss.end())
{
// printf("%s\n",tmps);
ss.insert(hs);
}
}
}
printf("%d\n",ss.size());
return 0;
}
AC参考:http://blog.youkuaiyun.com/waitfor_/article/details/8579700 4种方法。ac代码参考了这个blog差不多就不贴了。