[SCOI2009]windy数
Time Limit:1000MS Memory Limit:165536K
Total Submit:162 Accepted:74
Description
windy定义了一种windy数。
不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。
windy想知道,在A和B之间,包括A和B,总共有多少个windy数?
Input
包含两个整数,A B。
Output
一个整数。
Sample Input
【输入样例一】
1 10
【输入样例二】
25 50
Sample Output
【输出样例一】
9
【输出样例二】
20
【数据规模和约定】
20%的数据,满足 1 <= A <= B <= 1000000 。
100%的数据,满足 1 <= A <= B <= 2000000000 。
Source
Day1
http://61.187.179.132:8080/JudgeOnline/showproblem?problem_id=1026
状态:
令d[i][j]代表i位数,其中最高位为j的Windy数个数
状态转移方程:
d[i][j]=∑d[i-1][k](0≤k≤9且|k-j|≥2
边界:
d[1][j]=j
代码:
/* 令d[i][j]代表i位数,其中最高位为j的Windy数个数: d[i][j]=∑d[i-1][k](0≤k≤9且|k-j|≥2) */ #include<cstdio> #include<cstdlib> int i,j,k,d[20][10],t[]={0,1,10,100,1000,10000,100000,1000000,10000000,100000000,1000000000,-1u>>1}; void dp() { for(i=0;i<=9;i++) d[1][i]=1; for(i=2;i<=9;i++) for(j=0;j<=9;j++) for(k=0;k<=9;k++) if(abs(j-k)>=2) d[i][j]+=d[i-1][k]; for(j=1;j<3;j++) for(k=0;k<=9;k++) if(abs(j-k)>=2) d[10][j]+=d[9][k]; } int find(int n) { int i,j,k=1,num,last,ans=0; while(t[k]<=n)k++; k--; for(i=1;i<k;i++) for(j=1;j<=9;j++) ans+=d[i][j]; num=n/t[k]; for(j=1;j<num;j++) ans+=d[k][j]; n%=t[k]; last=num; for(i=k-1;i>0;i--) { num=n/t[i]; for(j=0;j<num;j++) if(abs(last-j)>=2) ans+=d[i][j]; if(abs(num-last)<2) break; last=num; n%=t[i]; } return ans; } int main() { dp(); int a,b; scanf("%d%d",&a,&b); printf("%d/n",find(b+1)-find(a)); }