蒟蒻求助!数位dp按照y总思路敲为什么只有30pts?
查看原帖
蒟蒻求助!数位dp按照y总思路敲为什么只有30pts?
698768
adolf_stalin楼主2022/8/15 19:15

RT,调了很久看不太出错,感觉是某一个数越界了

求大神指点!!!

#include <iostream>
#include <vector>

using namespace std;

long long base[20];
long long f[20][20];
long long g[20][20];

void init() {
	base[0] = 1;
	for(long long i = 1 ; i <= 18 ; i++) base[i] = base[i-1]*10;

	//从00……0 - 99……9 的各位数字有多少个,其中i为数字个数(包含前导零)
	for(long long i = 0 ; i <= 9 ; i++) f[1][i] = 1;
	for(long long i = 2 ; i <= 18 ; i++)
		for(long long j = 0 ; j <= 9 ; j++)
			f[i][j] = f[i-1][j]*10 + base[i-1];

	//从1 - 99……9 的各位数字有多少个,其中i为数字个数(不包含前导零)
	for(long long i = 1 ; i <= 9 ; i++) g[1][i] = 1;//循环从1开始
	for(long long i = 2 ; i <= 18 ; i++) {
		g[i][0] = g[i-1][0] + f[i-1][0]*9;
		for(long long j = 1 ; j <= 9 ; j++)
			g[i][j] = g[i-1][j] + f[i-1][j]*9 + base[i-1];
	}
}

vector<long long> dp(long long n) {
	vector<long long> ans(10,0); //记录答案
	if(n<=0) return ans; //边界条件

	vector<long long> nums;
	while(n) nums.push_back(n%10), n/=10;

	vector<long long> last(10,0); //记录前缀中各个数字个数

	//统计1 - 99……9(n-1个9)里面各个数字有多少个
	for(long long i = 0 ; i <= 9 ; i++) ans[i] = g[nums.size()-1][i];
	//统计大于10……0(n-1个0) 的树里各个数字有多少个
	for(long long i = nums.size()-1 ; i >=0 ; i--) {
		//循环变量i可以表示剩下的数字有多少个
		long long x = nums[i];
		for(long long j = i==nums.size()-1 ; j < x ; j++) { //第一次循环不能有0
			//前缀部分
			for(long long k = 0 ; k <= 9 ; k++)
				ans[k] += last[k] * base[i];
			//当前位置部分
			ans[j] += base[i];
			//后缀部分
			for(long long k = 0 ; k <= 9 ; k++)
				ans[k] += f[i][k];
		}
		//更新前缀计数器
		last[x] ++;

		//统计叶子节点(这个数本身)
		if(!i) for(long long k = 0 ; k <= 9 ; k++) ans[k] += last[k];
	}
	return ans;
}

vector<long long> ask(unsigned long long a, unsigned long long b) {
	auto x = dp(b);
	auto y = dp(a-1);
	vector<long long> ans;
	for(long long i = 0 ; i <= 9 ; i++) ans.push_back(x[i]-y[i]);
	return ans;
}

void print(vector<long long> ans) {
	for(auto x:ans) printf("%d ",x);
	printf(" ") ;
}

int main() {
	init();

	int a,b;
	cin >> a >> b ;
	if(a>b) 
		swap(a,b);
	auto t = ask(a,b);
	print(t);

	return 0;
}
2022/8/15 19:15
加载中...