社区讨论

蜜汁WA 80分

P2657[SCOI2009] windy 数参与者 7已保存回复 9

讨论操作

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

当前回复
9 条
当前快照
1 份
快照标识符
@mi6y44lp
此快照首次捕获于
2025/11/20 12:43
4 个月前
此快照最后确认于
2025/11/20 12:43
4 个月前
查看原帖
CPP
#include<bits/stdc++.h>
using namespace std;
long long f[15][10],power[15]={1};
//f[i][j]表示处理到i位且第i位是j的windy数的方案数 
long long count(long long x)
{
	long long cnt=0,ans=0;//cnt表示x有几位 
	while(power[cnt]<=x) cnt++;
	for(int i=1;i<cnt;i++)
		for(int j=1;j<=9;j++)
			ans+=f[i][j];
	for(int i=1;i<x/power[cnt-1];i++)
		ans+=f[cnt][i];
	
	//开始处理最难的部分
	//比如说考虑75420
	//考虑穷举完第四位的f[4][1~4]后,该位被确定
	//同理确定了754--后,不满足windy数,可以break
	
	//于是思路便来了
	//12~13行其实是上界,为特殊情况 
	//外循环枚举第几位,内循环累加
	//考虑到第一位无法取到,故输出处各加一 
	int last=x/power[cnt-1];
	x%=power[cnt-1];
	for(int i=cnt-1;i>=1;i--)
	{
		int y=x/power[i-1];
		for(int j=0;j<y;j++)
			if(abs(last-j)>=2)
				ans+=f[i][j];
		if(y-last<2) break;
		last=y;
		x%=power[i-1];
	} 
	return ans;
} 
void init()
{
	for(int i=0;i<=9;i++) f[1][i]=1;
	for(int i=2;i<=11;i++)
		for(int j=0;j<=9;j++)
			for(int k=0;k<=9;k++)
				if(abs(j-k)>=2)
					f[i][j]+=f[i-1][k];
	for(int i=1;i<=12;i++)
		power[i]=10*power[i-1];
}
int main()
{
	long long a,b;
	scanf("%lld%lld",&a,&b);
	init();
	cout<<count(b+1)-count(a)<<endl;
}

回复

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

正在加载回复...