zoukankan      html  css  js  c++  java
  • CF804B Minimum number of steps

    CF804B Minimum number of steps

    洛谷传送门

    题目描述

    We have a string of letters 'a' and 'b'. We want to perform some operations on it. On each step we choose one of substrings "ab" in the string and replace it with the string "bba". If we have no "ab" as a substring, our job is done. Print the minimum number of steps we should perform to make our job done modulo 10^{9}+7109+7 .

    The string "ab" appears as a substring if there is a letter 'b' right after the letter 'a' somewhere in the string.

    输入格式

    The first line contains the initial string consisting of letters 'a' and 'b' only with length from 11 to 10^{6}106 .

    输出格式

    Print the minimum number of steps modulo 10^{9}+7109+7 .

    题意翻译

    题面:

    你有一串字符串,仅由a,b组成,一次操作为"ab"->"bba",求使原串中没有a在b前面的操作次数. 输入格式:

    仅一行: 一串长为l的字符串(只由a,b组成). 输出格式:

    一个整数,即操作次数(%1e9+7). 数据范围:

    l:[1,1e6] 注意:

    None. 翻译贡献者:尘染梦

    输入输出样例

    输入 #1复制

    输出 #1复制

    输入 #2复制

    输出 #2复制

    说明/提示

    The first example: "ab" →→ "bba".

    The second example: "aab" →→ "abba" →→ "bbaba" →→ "bbbbaa".

    题解:

    这道题的暴力非常麻烦。所以我个人认为这道题要么是满分,要么是0分。

    我不讲0分思路

    因为这题不能用模拟,所以我们一定要从找规律和数学推导的地方入手去想。

    我们随便来几个ab串。通过对这些串的分析,我们发现:我们在转换的时候,把a一点一点往后移动,一定是最优的。而且我们在完成一个ab的转换之后,对之后的结果是没有影响的(就是我们继续向下转化不会因为这次的转化而出现错误)。

    那么,我们从头开始转,一定会在某一步出现这样的情况:

    由一串a后面跟一串b。

    类似:

    aaaaa..............bbbbbbbb.

    然后我们只需要考虑把这些A搞到后面去。这个时候应该从后往前推导,多用手模拟几次会发现,每次转换只将一个A依次右移,所以,我们要把所有A搞到后面去,应该会有:2的a的次数次幂减一次。

    通过以上的思路打码是比较困难的。但是因为这些步骤都是不互相影响的。所以我们完全可以推出下面的共同思路:

    碰到一个A,就把中间变量乘2(记得不断取模),碰到一个B,就统计一遍答案,是整个中间变量减一。

    代码如下,非常巧妙:

    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxl=1e6+1;
    const int mod=1e9+7;
    char s[maxl];
    int ans,temp=1;
    int main()
    {
        // freopen("seq.in","r",stdin);
        // freopen("seq.out","w",stdout);
        scanf("%s",s+1);
        int n=strlen(s+1);
        for(int i=1;i<=n;i++)
        {
            if(s[i]=='a')
                temp=(temp<<1)%mod;
            else
                ans=(ans+temp-1)%mod;
        }
        printf("%d",ans);
        return 0;
    }
    
  • 相关阅读:
    AX 2009 实现对display 方法过滤
    AX 2009实现数据验证方法
    AX 2009 实现outlook发送邮件并带多个附件
    AX 2009 销售订单导入导出
    Mixin技术与分布类编程
    关于python装饰器的总结
    作为软件工程师,你必须知道的20个常识
    Python装饰器基础语法总结
    如何成为一名黑客(转)
    python的对象和类
  • 原文地址:https://www.cnblogs.com/fusiwei/p/11673885.html
Copyright © 2011-2022 走看看