zoukankan      html  css  js  c++  java
  • ACM学习历程—CodeForces 176B Word Cut(字符串匹配 && dp && 递推)

    Description

    Let's consider one interesting word game. In this game you should transform one word into another through special operations.

    Let's say we have word w, let's split this word into two non-empty parts x and y so, that w = xy. A split operation is transforming word w = xy into word u = yx. For example, a split operation can transform word "wordcut" into word "cutword".

    You are given two words start and end. Count in how many ways we can transform word start into word end, if we apply exactly ksplit operations consecutively to word start.

    Two ways are considered different if the sequences of applied operations differ. Two operation sequences are different if exists such number i (1 ≤ i ≤ k), that in the i-th operation of the first sequence the word splits into parts x and y, in the i-th operation of the second sequence the word splits into parts a and b, and additionally x ≠ a holds.

    Input

    The first line contains a non-empty word start, the second line contains a non-empty word end. The words consist of lowercase Latin letters. The number of letters in word start equals the number of letters in word end and is at least 2 and doesn't exceed 1000 letters.

    The third line contains integer k (0 ≤ k ≤ 105) — the required number of operations.

    Output

    Print a single number — the answer to the problem. As this number can be rather large, print it modulo 1000000007(109 + 7).

    Sample Input

     
    Input
    ab
    ab
    2
    Output
    1
    Input
    ababab
    ababab
    1
    Output
    2
    Input
    ab
    ba
    2
    Output
    0

    Hint

    The sought way in the first sample is:

    ab → a|b → ba → b|a → ab

    In the second sample the two sought ways are:

    • ababab → abab|ab → ababab
    • ababab → ab|abab → ababab

    题目大意就是问有几种操作方法,能在k次操作下得到目标串。

    首先要肯定的是题目给的操作相当于一个循环串的位移。(位移不为0)

    这样的话,就可以对目标串的第一位分析了。

    记s(now, k)表示经过k次操作后,目标串的第一位在当前串的第now位。(初始k == 0时,由于串是循环串,会出现不止一个now的值不为0)

    于是s(now, k) = sum{s(i, k-1)} (i != now)

    只要不是本身就在now,都能位移到now。

    大一时做这个题,到就只能想到这里,然后进行了O(k*strlen(str)*strlen(str))的暴力运算。

    但是上述式子可以进行一定的变形:

    s(now, k) = sum - s(now, k-1)

    这样的话,只需要记录下sum,就能在O(k*strlen(str))的时间复杂度下完成了。

    需要注意的是,由于采用一维dp会导致计算s(now)的时候破坏了前一个状态。

    所以此处需要同时保存前一个状态和当前状态。所以开了第二维,且第二维仅保留两次的状态。(此处采用了亦或运算进行优化)

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #define N 1000000007
    
    using namespace std;
    
    char from[1005], to[1005];
    int n, len, s[1005][2], sum;
    
    bool Pair(int now)
    {
        int i = 0;
        for (;;)
        {
            if (i == len)
                return true;
            if (from[now] != to[i])
                return false;
            i++;
            now = (now+1) % len;
        }
    }
    
    bool Input()
    {
        if (scanf("%s", from) == EOF)
            return false;
        scanf("%s%d", to, &n);
        memset(s, 0, sizeof(s));
        len = strlen(from);
        sum = 0;
        for (int i = 0; i < len; ++i)
        {
            if (Pair(i))
            {
                s[i][0] = 1;
                sum++;
            }
        }
        return true;
    }
    
    void Work()
    {
        int tem, state = 0;
        for (int i = 1; i <= n; i++)
        {
            tem = 0;
            state = state^1;
            for (int j = 0; j < len; ++j)
            {
                s[j][state] = sum - s[j][state^1];
                s[j][state] = (s[j][state]%N+N)%N;
                tem += s[j][state];
                tem %= N;
            }
            sum = tem;
        }
        printf("%d
    ", s[0][state]);
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        while (Input())
        {
            Work();
        }
        return 0;
    }
  • 相关阅读:
    光电缆线路安防综合监控网管运维方案
    5G时代 微波通信网络运维管理系统实施方案
    IT运维管理之NETCONF工具
    新基建 破局大规模数据中心智能化监控运维管理
    智慧工厂工业交换机网络运维管理系统
    智慧轨道交通云联网安防运维集成化管理系统应用方案
    智和网管平台SugarNMS万能命令工具 赋能IT智能运维
    智慧城市综合运维安防监控管理系统方案
    SugarNMS可视化智能运维 赋能数据中心安全管控
    下载时,经常看见ASC、MD5、SHA1等,是干什么的呢?
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4512505.html
Copyright © 2011-2022 走看看