CODEFORCES 264D Colorful Stones

题目:http://codeforces.com/problemset/problem/264/D

题意:RBG组成的两个排石头组,松鼠和猫分别从石头的左端到右端,某一个时刻,你可以允许一种颜色的石头的石头通行。问松鼠和猫可以有多少组相对关系?

分析:状态、字符串,计数

Input
RBR
RGG
Output
5
Input
RGBB
BRRBRR
Output
19
Input
RRRRRRRRRR
RRRRRRRR
Output
8
Note

In the first example, there are five reachable states: (1, 1), (2, 2), (2, 3), (3, 2), and (3, 3). For example, the state (3, 3) is reachable because if you perform instructions "RED", "GREEN", and "BLUE" in this order from the initial state, the state will be (3, 3). The following picture shows how the instructions work in this case.

#include 
#include 
#include 
#include 
#define change(x) (x == 'R' ? 0 : (x == 'G' ? 1 : 2))
#define LL long long

using namespace std;

void tension(int &a, int &b)
{
    if (b < a)
        a = b;
}

const int MAXN =(int) 1e6 + 3;

int n, m;
char s[MAXN], t[MAXN];
int p1[MAXN], p2[MAXN];
int sum[MAXN][3][3];

void doing(char* const s, int n, char* const t, int m, int* const num)
{
    for (int i = 1; i <= n; i ++)
    {
        num[i] = num[i - 1] + 1;
        while (num[i] < m && t[num[i]] != s[i])
            num[i] ++;
        tension(num[i], m);
    }
}

int main()
{
    //printf("Hello world!\n");
    scanf("%s\n%s", s + 1, t + 1);
    n = strlen(s + 1);
    m = strlen(t + 1);
    doing(s, n, t, m, p1);
    doing(t, m, s, n, p2);
    for (int i = 2; i <= m; i ++)
    {
        for (int j = 0; j < 3; j ++)
            for (int k = 0; k < 3; k ++)
            {
                if (change(t[i - 1]) == j && change(t[i]) == k)
                    sum[i][j][k] = sum[i - 1][j][k] + 1;
                else
                    sum[i][j][k] = sum[i - 1][j][k];
            }
    }

    LL ans = 0;
    int L = 1;
    for (int i = 1; i <= n; i ++)
    {
        int R = p1[i];
        while (L <= m && p2[L] < i) L ++;
        ans += max(R - L + 1, 0);
        // printf("(%d,%d\n",i,L);
        if (L <= R && i > 1)
        {
            int j = change(s[i - 1]);
            int k = change(s[i]);
            if (j != k)
            {
                ans -= sum[R][k][j];
                ans += sum[L - 1][k][j];
            }
        }
    }
    cout << ans << endl;
    return 0;
}


你可能感兴趣的:(字符串问题:状态+计数)