hdu4346 枚举思维

http://acm.hdu.edu.cn/showproblem.php?pid=4346

Problem Description

There is a road from city A to city B.On the road,there are N positions(indexed from 0 to N-1).In order to celebrate the Multi-University training,the mayor of city A commands a worker to insert N flags on the N positions.The color of a flag is either red or
green.We call the road is beautiful if and only if there exists at least one pair of non-negative integers (a,b) (0<=a<b<N and (a+b) is an even number) such that both a-th flag and b-th flag are red and (a+b)/2-th flag is green.Otherwise we call the road is
ugly.Now,some positions have already been inserted flags.In order to make the road beautiful,the worker must carefully insert the flags on the positions which haven‘t been inserted.He wants to know how many different types of beautiful road he can make.The
type of the road only depends on the flags‘ color.

Input

The first line of the input is the number of cases. On each case there is a line consists of a string.The length of the string is N.(0<=N<=800).The i-th character of the string is ‘R‘ or ‘G‘ or ‘?‘.‘R‘ means the flag on the i-th position which has been inserted
is red.‘G‘ means the flag on the i-th position which has been inserted is green.‘?‘ means the i-th position hasn‘t been inserted a flag.

Output

A single line with the number of different types of road the worker can make,modulo 1,000,000,007.

Sample Input

4
?G
RG?
???
????

Sample Output

0
1
1
4
/**
http://blog.csdn.net/julyana_lin/article/details/7849006
*/
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
using namespace std;
typedef long long LL;
const int mod=1000000007;

LL mod_pow(int a,int n,int p)
{
    LL ret=1;
    LL A=a;
    while(n)
    {
        if(n&1)
        {
            ret=(ret*A)%p;
        }
        A=(A*A)%p;
        n>>=1;
    }
    return ret;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        char a[1005];
        scanf("%s",a);
        int n=strlen(a);
        int unknown=0,r_num=0;
        for(int i=0;i<n;i++)
        {
            if(a[i]=='?')
                unknown++;
            else if(a[i]=='R')
                r_num++;
        }
        LL unbea=(r_num==0);
        for(int i=0;i<n;i++)
        {
            if(a[i]=='R'||a[i]=='?')
            {
                int x=(a[i]=='R');
                unbea=(unbea+(x==r_num))%mod;
                for(int len=1;len+i<n;len+=2)
                {
                    int y=x;
                    for(int j=i+len;j<n;j+=len)
                    {
                        y+=(a[j]=='R');
                        if(a[j]=='G')break;
                        unbea=(unbea+(y==r_num))%mod;
                    }
                }
            }
        }
        printf("%I64d\n",mod_pow(2,unknown,mod)-unbea);
    }
    return 0;
}
时间: 2024-11-07 07:00:26

hdu4346 枚举思维的相关文章

CF851 D 枚举 思维

给出n个数,你可以对每个数把它变为0,或者增加1,分别需要花费x, y.问把所有数的GCD变为不为1的最小花费是多少. n的范围5x1e5,a[i]的范围1e6. 开始想通过枚举最终gcd值,然后通过判左右个数以及消费来二分,显然是愚蠢的想法,因为一个数在不同模数下余数并不单调阿! 实际上是枚举gcd值,首先a[i]只有1e6范围,预处理前缀和:cnt[i]表示前a[] < i的个数和,sum[i] 比i小的所有a[]的和. 这样在枚举gcd的倍数值时,只要找到gcd范围内的一个划分,小于该划分

CF543B Destroying Roads 枚举 + 思维 + BFS

Code: #include <bits/stdc++.h> #define ll long long #define setIO(s) freopen(s".in","r",stdin) #define maxn 3002 using namespace std; queue<int>Q; vector<int>G[maxn]; int n,m,s1,t1,l1,s2,t2,l2; int vis[maxn],d[maxn][m

!hdu 4091--贪心、枚举--(思维)

题意:有一个容量为n的箱子,有两种珠宝,占的体积和价值分别是s1,v1,s2,v2,求能装下的最大的价值总量. 分析:刚开始以为是背包问题,但其实没那么简单:后来分情况讨论还是不行:后来又暴力枚举,当然是超时了.正确做法是有一部分是用背包的贪心,另一部分用枚举!现在就是看哪一部分用贪心. 看别人的题解是:L = LCM(s1,s2),可是知道大于L的部分就用价值比高的,所以n%L的部分枚举,其余部分贪心,不过这样可能得到的还不是最优解,所以n%L+L的部分枚举,这样就可以了,具体原因我还没想明白

计算机程序的思维逻辑 (23) - 枚举的本质

前面系列,我们介绍了Java中表示和操作数据的基本数据类型.类和接口,本节探讨Java中的枚举类型. 所谓枚举,是一种特殊的数据,它的取值是有限的,可以枚举出来的,比如说一年就是有四季.一周有七天,虽然使用类也可以处理这种数据,但枚举类型更为简洁.安全和方便. 下面我们就来介绍枚举的使用,同时介绍其实现原理. 基础 基本用法 定义和使用基本的枚举是比较简单的,我们来看个例子,为表示衣服的尺寸,我们定义一个枚举类型Size,包括三个尺寸,小/中/大,代码如下: public enum Size {

一道有意思的思维题 --- 排序、枚举

这道题是在与学弟吃饭的路上听学弟讲的,感觉挺有意思的,需要不少的思维(可能我长时间没有刷题了,有点笨了~) 特此记录一下: Problem: 有n个(x,y)元组,求从中取出k个元组,使得这k个元组的x之和乘以其中最小的y值的值最大 ( sum(x)*min(y) in k个元组 ) Solution: 将n个元组按照y值从小到大排序,然后从小到大枚举每个y值,以当前的y值为选取的k个元组中的最小值,那么k个元组位于当前元组之后(一定包含当前元组).也就是说,有k-1个元组还未确定,需要从当前元

HDU 1172.猜数字【思路转换,思维练习】【枚举】【8月8】

猜数字 Problem Description 猜数字游戏是gameboy最喜欢的游戏之一.游戏的规则是这样的:计算机随机产生一个四位数,然后玩家猜这个四位数是什么.每猜一个数,计算机都会告诉玩家猜对几个数字,其中有几个数字在正确的位置上. 比如计算机随机产生的数字为1122.如果玩家猜1234,因为1,2这两个数字同时存在于这两个数中,而且1在这两个数中的位置是相同的,所以计算机会告诉玩家猜对了2个数字,其中一个在正确的位置.如果玩家猜1111,那么计算机会告诉他猜对2个数字,有2个在正确的位

Educational Codeforces Round 61 (Rated for Div. 2)F(区间DP,思维,枚举)

#include<bits/stdc++.h>typedef long long ll;const int inf=0x3f3f3f3f;using namespace std;char b[507];int dp[507][507];int main(){    memset(dp,0x3f,sizeof(dp));    int n;    scanf("%d",&n);    scanf("%s",b+1);    for(int i=1;

一道有意思的思维题2 --- 排序、枚举

这道题是又一次在和学弟吃饭的路上听学弟讲的,感觉挺不错的^_^,这样仿佛经常听学弟讲题能收获不少呀,可能明年笔试有望了,哈哈~ Problem: 平面上给了有n个人,位置由(x,y)元组给定,平面上还有m扇门,位置由(x,y)给定.现在约定每扇门只能进一个人,且人只能向左和下移动(向x-1和y-1移动),请问最多有多少人进门? Solution: 将人和门按x值从大到小排序,枚举门.对于当前枚举的门i,将值大于door[i].x的所有人的y值放入set中,找到大于等于door[i].y的最小值,

codeforces 493C Vasya and Basketball (枚举+模拟+思维)

C. Vasya and Basketball time limit per test 2 seconds memory limit per test 256 megabytes Vasya follows a basketball game and marks the distances from which each team makes a throw. He knows that each successful throw has value of either 2 or 3 point