衡阳八中1026windy数解题报告

来源:互联网 发布:阿里云服务器定时任务 编辑:程序博客网 时间:2024/04/29 22:54

1026: [SCOI2009]windy数

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 。
解题报告和代码都在code里:
/*如果没有看范神的代码的话,我会因为上下界的处理写一个很繁的代码,比如昨天比赛的那几道题。经过范神代码的启发,加之一个小修改优化了一维的时间复杂度。思路如下:先预处理出dp,dp[i][j]表示长度为i+1,并且第一个数字为j的总数。之后对于每组数据[a,b],用[0,b]里的总数-[1,a-1]里的总数。所以接下来的任务就是求[0,n]里的总数,程序里find函数实现。[0,n]可以等价转化为[0,n+1),这个转化在下面可以看到其巧妙之处。find实现过程:find(n)求的是[0,n)里的总数设n各位分别为a0 a1 a2... ak ( a0 > 0 )则可以拆解为求以下几个范围的总数的和:[ 0  0  0  0...0, a0  0  0  0... 0)[a0  0  0  0...0, a0 a1  0  0... 0)                [a0 a1  0  0...0, a0 a1 a2  0... 0)[a0 a1 a2  0...0, a0 a1 a2 a3... 0)...[a0 a1 a2 a3...0, a0 a1 a2 a3...ak)观察每个区间,前缀固定后,后缀都是某个满区间,比如第二行,a0固定后,只用求后缀[0,a1 0 0 0..0),而这个样子又和第一行相似      比如第三行,a0,a1固定后,只用求后缀[0,a2 0 0 0...0),这个样子和第一行相似于是乎,处理这些区间都是一个相似的过程:由前缀推导出现在的状态(设前缀为a0 a1 a2 ... ai),然后加上dp[k-i][j],0 <= j < ai+1,j还要符合题意里的约束条件。此时只需要两层循环就可以求出结果了。要注意的是,某个前缀已经不符合条件时,之后的区间就不用枚举了。另外在求第一行那个区间时,由于最高位非0的问题,不能dp[i][0]了事,而要枚举dp[i][1..9]的和。代码如下:*/#include <cstdio>#include <numeric>#include <cstring>using namespace std;int dp[15][10];int abs(int a){return a<0?-a:a;}//dp预处理出来void DP(){memset(dp,0,sizeof(dp));for(int i = 0 ; i < 10 ; i++ )dp[0][i] = 1;for(int i = 1 ; i < 10 ; i++ )for(int j = 0 ; j < 10 ; j++)for(int k = 0 ; k < 10 ; k++)if(abs(j-k)>1)dp[i][j]+=dp[i-1][k];}int find(int n){int ans = 0;char s[15];sprintf(s,"%d",n);int len = strlen(s);//对于第一行区间的求解for(int i = 0; s[i+1]; i++)ans += accumulate(dp[i]+1,dp[i]+10,0);//对于第二行直到最后的求解,i的条件判断是对前缀的判断,j的起点也根据是否是第一位而有所不同for(int i = 0; s[i] && (i<2 || abs(s[i-1]-s[i-2])>1); i++)for(int j = !i ? 1 : 0 ; j < s[i]-'0' ; j++)ans += dp[len-i-1][j] * ( !i || (abs(j-s[i-1]+'0')>1));return ans;}int main(){int a,b;DP();while(scanf("%d %d",&a,&b)==2){printf("%d\n",find(b+1)-find(a));}return 0;}//此题的思路是hdu3565bi-PeakNumber的前导,这个思想只是处理了上界,同理可以拓展到处理下界

进阶题目:hdu3565 Bi-peak Number及结题报告
原创粉丝点击