社区讨论

WA 0分求调

P2602[ZJOI2010] 数字计数参与者 2已保存回复 6

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
6 条
当前快照
1 份
快照标识符
@mlgxw30o
此快照首次捕获于
2026/02/11 02:33
上周
此快照最后确认于
2026/02/11 02:33
上周
查看原帖
感觉我的代码太猎奇了还是讲一下思路吧
fi,af_{i,a}ii 位数结尾为 aa 的方案数(允许前导零):
fi,a=fi1,a×10+10i1f_{i,a}=f_{i-1,a}\times10+10^{i-1}
然后为了避免前导零被算入记录0时的答案:
fi,0fi,0j=0i110jf_{i,0} \leftarrow f_{i,0}-\sum_{j=0}^{i-1}10^j
如果思路错了,可以指出问题吗qwq
感谢乐于助人的大佬。
CPP
#include<iostream>
#define int long long
using namespace std;
int a,b,f[15][15],digit[15],top;
int pow_10(int x){
	int ans=1;
	for(int i=1;i<=x;i++) ans*=10;
	return ans;
}
void init(){
	for(int i=0;i<=9;i++) f[1][i]=1;
	for(int i=2;i<=13;i++){
		for(int j=0;j<=9;j++){
			f[i][j]=f[i-1][j]*10+pow_10(i-1);
		}
	}
    for(int i=2;i<=13;i++){
        for(int j=0;j<=i-1;j++){
            f[i][0]-=pow_10(j);
        }
    }
}
int solve(int x,int d){
	top=0;
	while(x){
		digit[++top]=x%10;
		x/=10;
	}
	int ans=0;
	for(int i=top;i>=1;i--){
		for(int j=0;j<(digit[i]+(i==1));j++){
            ans+=f[i-1][d];
            if(j==d&&j) ans+=pow_10(i-1);
            if(i+1<=top&&digit[i+1]==d) ans+=pow_10(i-1);
        }
	}
    return ans;
}
signed main(){
	init();
	cin>>a>>b;
	for(int i=0;i<=9;i++) cout<<(solve(b,i)-solve(a-1,i))<<" ";
}

回复

6 条回复,欢迎继续交流。

正在加载回复...