[NOIP模拟赛]RGB

37 篇文章 1 订阅
17 篇文章 0 订阅
题目描述

给出一个长度为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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值