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;
    }
    
  • 相关阅读:
    从B树、B+树、B*树谈到R 树
    1.红黑树和自平衡二叉(查找)树区别 2.红黑树与B树的区别
    红黑树 Java实现
    自平衡二叉(查找树/搜索树/排序树) binary search tree
    从零开始: 二叉查找
    深入理解JAVA虚拟机JVM
    java中的变量各占得字节数
    java中new两个对象,在堆中开辟几个对象空间
    Spring面试,IoC和AOP的理解, @Transactional原理及使用
    EasyUI Tabs + Yii2.0实现iframe方式打开页面(解决共用静态文件引入加载的问题)
  • 原文地址:https://www.cnblogs.com/fusiwei/p/11673885.html
Copyright © 2011-2022 走看看