jzoj 3843. 寻找羔羊(agnus) (Standard IO)

Description
给定一个由小写字母组成的字符串,寻找包含“agnus”(羔羊)的子串的个数。注意:当且仅当两个子串的起始位置和终点不同时,这两个子串属于不同的子串。

Input
只有一个字符串,表示题中所述的字符串。

Output
仅一个数字,表示满足题意的子串个数。

Sample Input

agnusbgnus

Sample Output
6
【样例解释】
6个子串分别是:agnus、agnusb、agnusbg、agnusbgn、agnusbgnu、agnusbgnus。

Data Constraint
对于 40%的数据,字符串长度<=1000
对于 100%的数据,字符串长度<=30000

//written by zzy

题目大意:

给你个字符串,求这个串中有多少个子串(字母连续)中有agnus

题解:

容斥,用总的所有子串个数减去不合法的子串个数
例如:S为
XXagnusXXX
12345678901234567890
总的子串个数为10(10+1)/2=5510*(10+1)/2=55
其中s[16]s[1-6],s[410]s[4-10]的所有子串不合法,总答案减去6(6+1)/2+7(7+1)/2=496*(6+1)/2+7*(7+1)/2=49
s[46]s[4-6]中的所有子串被减了两次,要加回3(3+1)/2=63*(3+1)/2=6
答案为5549+6=1255-49+6=12

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define N 30005
using namespace std;

int i,j,n=0,m,p,l,ans,re;
int f[N];
char s[N];

int num(int x) {
	return x*(x+1)/2;
}

int main()
{
	scanf("%s",s);
	l=strlen(s);
	ans=num(l);
	for (i=0;i<l;i++) 
	 if (s[i]=='a'&&s[i+1]=='g'&&s[i+2]=='n'&&s[i+3]=='u'&&s[i+4]=='s')
	  f[++n]=1,i+=4,re++; 
	  else f[++n]=0;
	p=0;
	for (i=1;i<=n;i++)
	 if (f[i]==1) {
        if (p==0) ans-=num(i+3); 
        else ans-=num(i-p+7);
        p=i;
	 }
	ans-=num(n-p+4);
	ans+=re*6; 
	printf("%d",ans);
} 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章