[海豹海边爆]Daimayuan498

该博客主要介绍了如何高效地解决加一操作后数字位数变化的问题。通过预处理每个数字单独加一操作后的位数,并存储在一个二维数组中,实现了在查询时能快速得到给定数字在执行多次加一操作后的位数。文章详细讲解了预处理过程和查询算法,并提供了完整的C++ AC代码实现。
摘要由CSDN通过智能技术生成

原题链接:加一 - 题目 - Daimayuan Online Judge

解题思路:首先预处理一下每个数字单独存在时,执行不同加一操作后产生几位数字。用一个二维数组储存,一维是操作数,一维是初始数字。

之后查询时,将原数字拆成每一位单独的数字后直接查数组,O(1)复杂度就能查到这个数字在执行这么多次操作后的位数。

而预处理每一位数字,只需要开一个0-9的数组,储存这十个数字当前分别有几个。在0-8的每一个数字,每执行一次加一操作就是往后挪一位。而9在执行操作后,将里面储存的数量直接赋值给0,用以模拟进位变成10后的那个0。同时也将这个值加给1,代表十位上的1。此时,进位后的数字以及拆成两个单独的数了,接着不断重复即可。

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
long long len[10][200010];//储存0-9每个数在执行不同操作数后的位数 
void pre_work(){//预处理函数 
	long long dp[10],buffer;
	for(int i=0;i<=9;i++){
		memset(dp,0,sizeof(dp));//初始化 
		len[i][0]=1;//不执行操作肯定是1位 
		dp[i]=1;//设置起始点 
		for(int j=1;j<=200010;j++){
			buffer=dp[9];//缓存9的数量 
			for(int k=9;k>0;k--){
				dp[k]=dp[k-1];
			}
			dp[0]=buffer;//一定不能是累加,因为事实上0的值在+1后已经挪到1了,里面的只是残余的无用数字 
			dp[1]+=buffer;
			for(int k=0;k<=9;k++){//累加这次操作后一共有几位 
				dp[k]%=mod;
				len[i][j]+=dp[k];
				len[i][j]%=mod;
			}
		}
	}
	return;
}
int main(){
	long long t,m,n;
	pre_work();//预处理函数 
	cin>>t;
	while(t--){
		long long ans=0;
		scanf("%lld %lld",&n,&m);
		while(n){//循环拆分并查询这个数字在执行m次操作后的位数 
			ans+=len[n%10][m];
			ans%=mod;
			n/=10;
		}
		printf("%lld\n",ans);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值