HDU 4346 The Beautiful Road ( 反向考虑 思路题 )

考虑对立情况,不漂亮的串的形式必然为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;
}
原文地址:https://www.cnblogs.com/GBRgbr/p/3352006.html