题目描述
给出一个长度为n的字符串S,其中只包含'R','G','B'三种字符,下标从0开始。给出一个整数m,求有多少个四元组(a,b,c,d)满足a ≤ b, c ≤ d, b < c,目标串T=S[a~b]+S[c~d]中至少包含连续的m个'G'。
输入格式
第1行:1个字符串,表示S(n≤10000)
第2行:1个整数,表示m(m≤10000)
输出格式
第1行:1个整数,表示答案
输入样例
GRG
2
输出样例
1
样例说明
唯一合法的四元组是 (0,0,2,2),对这个四元组,S[a~b]="G" 且S[c~d]="G", 因此T = "GG"。
题解
之后再写
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; typedef long long LL; const int N=10005; int n, m, p[N], psum[N], jud, cnt; LL sum; bool col[N]; /* psum[i]表示在当前扫描到的位置之前, 结尾‘G’个数大于等于i的字串的个数的前缀和, 如果包含的连续的G已经符合要求, 加在psum[minG] p[i]表示以当前扫描位置结束, 结尾‘G’个数大于等于i的字串的个数, 如果包含的连续的G已经符合要求, 加在p[minG] */ void Gcnt( int j ) {//扫描以当前位置开头的串, 更新答案 jud=-1; cnt=0; for( ; j<=n; j++ ) { if( col[j] ) { if( ++cnt>=m ) jud=m; } else { if( jud==-1 ) jud=cnt; cnt=0; } if( jud==-1) sum+=psum[ m-cnt ]; else sum+=psum[ m-jud ]; } } void Rearr( int j ) {//扫描以当前位置结尾的串, 更新前缀和 memset( p, 0, sizeof p ); jud=-1; cnt=0; for( ; j>=1; j-- ) { if( col[j] ) { if( ++cnt>=m ) jud=m; } else{ if( jud==-1 ) jud=cnt; cnt=0; } if ( jud==-1 ) p[cnt]++; else p[jud]++; } for( j=n-1; j>=0; j-- ) p[j]+=p[j+1]; for( j=n; j>=0; j-- ) psum[j]+=p[j]; } int main() { while( char c=getchar() ) { if( c=='\n' || c=='\r' ) break; col[++n]=(c=='G'); } scanf( "%d", &m ); for( int i=1; i<=n; i++ ) Gcnt(i), Rearr(i); printf( "%I64d\n", sum ); return 0; }
[NOIP模拟赛]RGB
最新推荐文章于 2024-08-07 17:53:53 发布