考虑对立情况,不漂亮的串的形式必然为GGGGR……R……RGGGG
相邻R之间的距离为奇数且相等。
#include <cstdio> #include <cstring> #include <cstdlib> #define LL long long int using namespace std; const int MAXN = 888; const LL MOD = 1000000007; char str[MAXN]; int main() { int T; scanf( "%d", &T ); while ( T-- ) { scanf( "%s", str ); int len = strlen(str); LL unknown = 0; LL Rnum = 0; for ( int i = 0; i < len; ++i ) { switch( str[i] ) { case '?': ++unknown; break; case 'R': ++Rnum; break; default:; } } LL res = 0; //如果全是G if ( Rnum == 0 ) ++res; //枚举R的起点 for ( int i = 0; i < len; ++i ) { if ( str[i] == 'G' ) continue; //如果只有一个R if ( str[i] == 'R' && Rnum == 1 ) res = ( res + 1 ) % MOD; else if ( str[i] == '?' && Rnum == 0 ) res = ( res + 1 ) % MOD; //至少有两个R, 枚举间距 for ( int dis = 1; i + dis < len; dis += 2 ) { int cnt = (str[i] == 'R'); //统计R的个数 //从第二个位置开始遍历 for ( int k = i + dis; k < len; k += dis ) { if ( str[k] == 'G' ) break; if ( str[k] == 'R' ) ++cnt; //记录经过的R的个数 //如果经过的R的个数等于已知的R的个数,不漂亮的串的个数+1 //从k之前是RG交替,从k之后全部是G //printf( "dis=%d i=%d k=%d cnt=%d ", dis, i, k, cnt ); if ( cnt == Rnum ) res = ( res + 1 ) % MOD; } } if ( str[i] == 'R' ) break; } LL all = 1; for ( int i = 0; i < unknown; ++i ) all = (all * 2) % MOD; //printf("%I64d %I64d ", all, res ); printf("%I64d ", ( all - res + MOD ) % MOD ); } return 0; }