http://codeforces.com/problemset/problem/144/C
定义: S的“乱序串” ,就是 一个串P经过任意排列和 ,能变成串S(完全匹配)
给一个串S,(字母和?) 问号表示任意字母
给一个P(只有字母)
问你S串的所有子串里,有多少个子串可以是P的乱序串。
直接for一遍 on,
预处理 P的所有字母 到vis[26]
然后遍历S串,每遇到一个字母 把vis_s【】里面的数值更新,并更新变量marks(问号数量)
然后当子串长度与p相等的时候,判断是否和P完全相同(包含问号判断),就OK啦。
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
__int64 min(__int64 a,__int64 b)
{return a<b?a:b;}
__int64 max(__int64 a,__int64 b)
{return a>b?a:b;}
char s[100005],p[100005];
int vis[28];
int sss[28];
int marks=0;
int main()
{
int i,j;
scanf("%s",s);
scanf("%s",p);
int lens=strlen(s);
int lenp=strlen(p);
if (lenp>lens)
{
printf("0\n");return 0;
}
for (i=0;i<lenp;i++)
vis[p[i]-'a']++;
int ans=0;
int cun=0;
int st=0;
for (i=0;i<lens;i++)
{
cun++;
if (s[i]=='?') marks++;
else
sss[s[i]-'a']++;
if (cun==lenp)
{
int less=0;
int flag=0;
for (j=0;j<26;j++)
{
if (vis[j]==sss[j]) continue;
else
if (sss[j]<vis[j]) less+=vis[j]-sss[j];
else
{flag=1;break;}
}
if (!flag)
{
if (less==0) ans++;
else if (less==marks) ans++;
}
cun--;
if (s[st]=='?') marks--;
else
sss[s[st]-'a']--;
st++;
}
}
printf("%d\n",ans);
}