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\n", 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\n", all, res );

        printf("%I64d\n", ( all - res + MOD ) % MOD );

    }

    return 0;

}

 

你可能感兴趣的:(HDU)