Codeforces Round #714 (Div. 2) C. Add One

Divide by Zero 2021 and Codeforces Round #714 (Div. 2)

C Add One

看大佬都是打表做的,是因为操作的数据范围不大

看题意,每一位增加1不会进位到下一位,而是在前面直接增加一个1,所以我们可以直接对每个数组操作m次后看它会变成几位

在我们观察来看,只有当该位为9的时候,把他加一才会产生新的位数,也就是对答案做出了贡献

而每进一位,1的个数就会多一个

所以每一个数字出现了几次,每一个数字都会站一位,所以操作后的长度就是每个数字出现的个数

然后对询问的答案,我们每一位拆分之后把该位对应的数字变成几位的答案累加就行了

// Problem: C. Add One
// Contest: Codeforces - Divide by Zero 2021 and Codeforces Round #714 (Div. 2)
// URL: https://codeforces.com/contest/1513/problem/C
// Memory Limit: 256 MB
// Time Limit: 1000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <map>
#include <vector>
#include <set>
#include <queue>
#include <stack>
#include <sstream>
#define ll long long
#define re return

using namespace std;

const int MOD = 1e9 + 7;

typedef pair<int, int> PII;

int dx[4] = {-1,0,1,0};
int dy[4] = {0,1,0,-1};

int n;
int m;
int ans[200000 + 10][10]; // 用来记录每个数字经过m次操作后长度为几


void init(){
	for(int i = 0; i <= 9; i++){
		ans[0][i] = 1; // 操作0次答案自然就是1
		
		
		ll cnt[10] = {0}; // 每个数在每次操作后出现了多少次
		ll t[10] = {0}; // 这个数在在m次操作中的某一个操作中,每个数出现了多少次		
		cnt[i]++; // 这一个数字出现过一次
		
		for(int j = 1; j <= 200000; j++){
			
			for(int k = 0; k <= 9; k++){
				t[(k + 1) % 10] = cnt[k]; //每一位数字加一后变成新的数字,但他不会对答案做出贡献
			}
			
			t[1] += cnt[9]; // 9在操作后会新增出来一个1,1的个数就会变多了
			
			ll summ = 0;
			
			for(int k = 0; k <= 9; k++){
				summ += t[k]; // 提议分析
				summ %= MOD;
				cnt[k] = t[k] % MOD; // 下一次操作,每个数分别有几个
			}
			
			 ans[j][i] = summ;
			
		}
		
	}
}

void work(){
	char s[20];
	scanf("%s%d", s, &m); // 打表卡cin
	
	ll a = 0;
	int l = strlen(s);
	
	ll a = 0;
	for(int i = 0; i < l; i++){
		a = (a + ans[m][int(s[i] - '0')]) % MOD; // 答案构成
	}
	
	printf("%lld\n", a % MOD);
}


int main(){
	init();
	int T;
	cin >> T;
	while(T--){
		work();
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值