Comet OJ - Contest #1 B +1 复读(暴力)

题目描述

在许多讨论算法的 qq 群里面,很多人都喜欢复读。在这里复读是重复上一个人所说的一模一样的话的意思。

但也有很多人讨厌看到其他人一直在复读,觉得这会给其他人带来困扰,所以有些 qq 群会禁止大家复读。

于是这些喜欢复读的人又发明了各种复读的变形方式,+1 复读就是其中一个例子。

这里举个 +1 复读的例子,当有个人说:“羡慕+1”,则接下来喜欢复读的人会接着说:“羡慕+2”, “羡慕+3”, “羡慕+4”, …

很喜欢复读的 dreamoon 看到这个现象后想到了一个问题如下:

对于给定一个由数字字符 ‘0’ 至 ‘9’ 组成的字符串,若选择其中一个子字符串组成的数字加 11 后并取代原子字符串,有多少种可能的不同结果?

原字符串的开头允许多余的 ‘0’ ,但选取来要加 11 的子字符串的开头不能有多余的 ‘0’ 。

观看提示可帮助你更了解题意。

输入描述

第一行有一个正整数 TT (T \le 2 \times 10^5T≤2×10
5
),代表有几组数据。

接着每组数据一行,包含一个由数字字符 ‘0’ 至 ‘9’ 所组成的字符串,其长度为不超过 2 \times 10^52×10
5
的正整数。

全部数据的字符串总长度不超过 10^610
6

输出描述

对于每组数据,输出一个整数于一行代表答案。

样例输入 1

4
0
19
921
100
样例输出 1

1
3
3
3
提示

对于样例中第二组数据,有三种可能子字符串选择方式,分别是 ‘1’, ‘9’, ‘19’,加 11 后分别是 ‘2’, ‘10’, ‘20’,取代回原字串后分别是 ‘29’, ‘110’, ‘20’,总共有三种不同可能。

对于样例中第三组数据,有六种可能子字符串选择方式,分别是 ‘9’, ‘2’, ‘1’, ‘92’, ‘21’, ‘921’,加 11 后分别是 ‘10’, ‘3’, ‘2’, ‘93’, ‘22’, ‘922’,取代回原字串后分别是 ‘1021’, ‘931’, ‘922’, ‘931’, ‘922’, ‘922’,总共有三种不同可能。

对于样例中第四组数据,有五种可能子字符串选择方式,分别是 ‘1’, ‘0’, ‘0’, ‘10’, ‘100’,加 11 后分别是 ‘2’ , ‘1’, ‘1’, ‘11’, ‘101’,取代回原字串后分别是 ‘200’, ‘110’, ‘101’, ‘110’, ‘101’,总共有三种不同可能。

通过提示可以很明了的看出题意

思路: 串分为前导0和非前导0,将串处理成去除前导0的新串,再进行操作。
根据题意我们可以知道,只要当前字符不为9,进行+1操作后,以当前字符串为尾的字串结果均不变,其余看连续9的情况,当当前字符为9时,又分为第一个字符为9,和第一个字符不为9。
第一个字符为9时,则它的连续9的子字符串,第一个9为ans提供1,第二个9为ans提供2,第三个9为ans提供3,依次类推…
第一个字符不为9时,则它的子串中连续9的子字符串,第一个9为ans提供2,第二个9为ans提供3,第三个9为ans提供4,依次类推…

错误原因:
没有加ll,挂掉了,心态炸了!!!

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        int flag=0;
        string s,s1;
        cin>>s;
        for(int i=0;i<s.size();i++){
            if(s[i]!='0'&&!flag)    flag=1;
            if(flag)    s1+=s[i];
        }
        ll ans=0,w=1;
        for(int i=0;i<s1.size();i++){
            if(s1[i]!='9') w=1, ans++;
            else{
                if(i==0)    w--;
                w++;
                ans+=w;
            }
        }
        cout<<1ll*(ans+s.size()-s1.size())<<endl;
    }
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值