nyist oj 1172 unlucky number
来源:互联网 发布:乐秀软件下载 编辑:程序博客网 时间:2024/06/07 05:11
unlucky number
- 描述
- 我们定义在区间【l,r】之间只出现1和7组合的数是unlucky number,例如:1 、7、 11、17 都是unlucky numbers ,而 13 、27则不是,问在区间【l,r】内有多少 unlucky numbers??
- 输入
- 有多组测试数据(不超过100组)
每组输入两个整数l,r( 0 =< l<= r <= 10^18) - 输出
- 每行输入一个结果
- 样例输入
1 7
- 样例输出
2
假设有两个数组a[n]和b[n],a[i]表示i位数中共有多少种1和7的组合,我们看看怎么求a[i],首先看第一位,有两种选择(1和7),再看第二位,有两种选择,依次进行,每一位都是两种选择,根据分步乘法计数原理,a[i]=2^i。
b[i]表示1~10^i之间共有多少种1和7的组合,显然b[i]=a[1]+a[2]+a[3]+……a[i]=2^(i+1)-2,即b[i]=(b[i-1]+2)*2-2。
如果计算l~r之间的1和7的组合数,假设某函数f(n)可以计算1~n之间的组合数,则结果等于f(r)-f(l-1),但是如果l是一个字符串的大数的话,还要计算大数减法,为了避免这种情况,可以计算f(r)-f(l),然后如果l是1和7的组合的话,再加上1就行了,简单了许多。
那么如何计算任意一个数的符合条件的数的数目,比如8817,首先在1~1000之内有b[3]个数,然后当千位分别是1和7时,都有a[3]个数,所以是2*a[3],所以总共的情况有b[3]+2*a[3]=30,但是只有这么简单吗,是的,在这个情况下,他只需要O(1)的复杂度,但对于最坏的情况,比如7720,首先在1~1000之内有b[3]个数,然后当千位分别是1时,有a[3]个数,所以是a[3],当千位是7时,他的具体数目要往后面看,看百位是7,当是1时,有了a[2]种可能,当成为7时,还要往后看,十位是2,此时当十位是1时,包含了所有情况,即只有a[1],即所有的可能为b[3]+a[3]+a[2]+a[1]=28。基于此思想,可以形成最坏O(N)复杂度的算法,其中n为字符串的长度,所以此计数不只是局限于long long 内,以下是代码,仅供参考
#include <cstdio>#include <cstring>int dp[24];int cau(char *s){ int len=strlen(s),sum,num,flag; sum=dp[len-1];flag=1; for(int i=0;i<len-1;i++){ num=s[i]-'0'; if(num==0) break; if(num==1) {if(i==len-2) flag=0;continue;} if(num<7) {sum+=dp[len-1-i]-dp[len-2-i];break;} if(num==7) {sum+=dp[len-1-i]-dp[len-2-i];if(i==len-2) flag=0;continue;} sum+=dp[len-1-i]-dp[len-2-i]+dp[len-1-i]-dp[len-2-i];break; } if(flag&&len>1) return sum; num=s[len-1]-'0'; if(num<1) return sum; if(num<7) return sum+1; return sum+2;}char h1[24],h2[24];int main(){ dp[1]=2;dp[2]=6; for(int i=3;i<=24;i++) dp[i]=(dp[i-1]+2)*2-2; while(scanf("%s%s",h1,h2)!=EOF){ int j=1,len=strlen(h1); for(int i=0;i<len;i++){ if(h1[i]=='1'||h1[i]=='7') continue; j=0;break; } printf("%d\n",cau(h2)-cau(h1)+j); } return 0;}
以上代码中,dp数组就是代表b数组,h2和h1字符串分别表示r和l这两个数。cau()就是以上说的f()函数。
这个代码还可以再写短一点,让它更美观,不过这不是问题的主要矛盾,还有一个问题,这个cau函数真的能计算任意长度的数字吗,其实,最好的情况下,在计算cau(n)时,当n=10^31时,就会有2^32-2种可能,超出了int的范围,就算把cau()的返回值设为long long,那么n=10^63时,会超出范围,所以这个代码是不完美的,但可以修正,只要把cau()函数的返回值改为字符串,其中的加法改为大数加法就行了,就可以支持任意有限位的整数。- nyist oj 1172 unlucky number
- nyoj 1172 unlucky number
- NYOJ---题目1172unlucky number
- unlucky number
- Unlucky Number I
- light oj 1311 - Unlucky Bird (物理啊)
- nyoj unlucky number 1184 (**打表**)
- nyist oj nyoj 865
- Light OJ 1268 Unlucky Strings 矩阵快速幂+KMP
- nyist oj 756 重建二叉树
- NYIST OJ 1000 又见Fibonacci数列
- nyist 413 && poj 1019 Number Sequence
- nyist
- nyist oj 239 月老的难题 解决超时问题
- nyist oj 38 布线问题 (最小生成树 prim)
- nyist oj 58 最少步数(dfs搜索)
- nyist oj 115 城市平乱 (最短路径)
- nyist oj 540 奇怪的排序(水题)
- android 从相册中选择图片并判断图片是否旋转
- IOS 升级78 AutoLayout 概述 (二)
- Copy file to / from server via SCP command
- c++类的构造函数详解
- makefile详解 make 的运行
- nyist oj 1172 unlucky number
- 事务与锁(转)
- [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- 利用头插法实现单向链表的逆置
- 如何对待日新月异的软件技术
- How to create user defined properties in Maven
- Bitmap插入二进制字符串及解析
- vim使用方法
- 2014阿里巴巴实习生笔试题目 .