| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2416 人关注过本帖
标题:连续奇数乘积的二进制位
取消只看楼主 加入收藏
ivapple
Rank: 1
等 级:新手上路
帖 子:46
专家分:0
注 册:2008-7-31
收藏
 问题点数:0 回复次数:5 
连续奇数乘积的二进制位
最经碰到这样一个题,我用的方法做了下,可惜算的太慢了,还请各位帮忙,谢谢了,o(∩_∩)o...
给定一连续奇数数列,它们的积有几个二进制位?
Input
第一行为一个数n,表示数列的个数。下面每行两个奇数a,b(1<=a<=b<=10,000,000),分别为数列的首项和末项。
Output
对每个数列,输出一行,该行只有一个整数,表示积的二进制位数。
Sample Input
2
1 3
11 13
Sample Output
2
8
这是我写的程序
#include<stdio.h>
#include<math.h>
#define LOG log(2)
int main(){
    int n;
    int start,end;
    int i,result;
    int mul;
    int preMul;
    while(scanf("%d",&n)!=-1){
          for(i=0;i<n;i++){
              scanf("%d%d",&start,&end);
              result=1;
              mul=1;
              preMul=1;
              while(start<=end){
                  preMul=mul;
                  mul*=start;
                  if(mul/start!=preMul){
                     result+=int(log(float(preMul))/LOG);
                     preMul=1;
                     mul=1;
                     start-=2;
                  }
                  start+=2;
              }
              result+=int(log(float(mul))/LOG);
              printf("%d\n",result);
          }
    }
    return 0;
}
搜索更多相关主题的帖子: 二进制 乘积 奇数 
2008-08-21 17:00
ivapple
Rank: 1
等 级:新手上路
帖 子:46
专家分:0
注 册:2008-7-31
收藏
得分:0 
谢谢你的支持!
可是要是数列很长,光是乘积的话可能就溢出了。
比如输入1 10000000
我的计算出来是106610241位二进制数(33位就超int了),目测用了有1s
但是不知道对不对。可能误差累积错了也说不定。
有没有能解决乘积溢出而且很快的算法呢?
再次谢谢你的支持。o(∩_∩)o...
2008-08-23 00:38
ivapple
Rank: 1
等 级:新手上路
帖 子:46
专家分:0
注 册:2008-7-31
收藏
得分:0 
可是题目将来的测试数据就一定会有这种极限的测试
(下面每行两个奇数a,b(1<=a<=b<=10,000,000),分别为数列的首项和末项),
确实可以通过大数类解决范围问题。
那时间上怎么办,一般都要在1s左右啊!我的意思是说这题应该有快速的解法。
这种东西就是考范围和精度 。一般的二进制转化差不多大家都会。其实它只要位数,并不要具体的二进制数,要是那样的话,无论如何都快不了的。光输出上亿位的二进制数就要很久了。
看了你好多贴。阁下的数据结构功底我很佩服。我才入门。
不知你主要看那本书,看你的编程风格像是殷版的。
还有你的大数类我得粘回去慢慢看看,谢谢你的程序。

[[it] 本帖最后由 ivapple 于 2008-8-23 19:59 编辑 [/it]]
2008-08-23 19:55
ivapple
Rank: 1
等 级:新手上路
帖 子:46
专家分:0
注 册:2008-7-31
收藏
得分:0 
猜对了,呵呵!
共勉共勉。
2008-08-23 20:51
ivapple
Rank: 1
等 级:新手上路
帖 子:46
专家分:0
注 册:2008-7-31
收藏
得分:0 
这个问题我解决了。
用阶乘来转换连续奇数乘积。
比如
1*3*5*7=7!/(2*3!)
然后用斯特林公式近似求阶乘
当然是求取对数的,否则溢出。可在常数时间内完成。
程序如下:
#include<stdio.h>
#include<math.h>
const double LOG=log(2);const double PRE=sqrt(2*3.1415926535);double logfac(int n){double i=1.0;  if (n<=9){if(n==0)
             i=0;else{while(n>0)i=i*n--;i=log(i);}}else i=log(sqrt(n)*PRE)+n*log(n)-n;return i;}
int main(){int n,i;int start,end;int result;while(scanf("%d",&n)!=-1){for(i=0;i<n;i++){scanf("%d%d",&start,&end);if(start==end)result=int(log(start)/LOG)+1;
              else{if(start>=3)result=int((log(start)+logfac(end)-logfac(start)-logfac(end/2)+logfac(start/2))/LOG-end/2+start/2)+1;if(start==1)
                     result=int((log(start)+logfac(end)-logfac(end/2))/LOG-end/2)+1;if(end==1)result=1;}printf("%d\n",result);}}return 0;}
程序有点乱,但可以运行(DEV C++ 4.9.9.2和VC 6.0通过)。
a=1
b=10000000
都能算
共有109054009位二进制位,不信的话,自己去验证,o(∩_∩)o...

[[it] 本帖最后由 ivapple 于 2008-9-15 15:39 编辑 [/it]]
2008-09-15 14:57
ivapple
Rank: 1
等 级:新手上路
帖 子:46
专家分:0
注 册:2008-7-31
收藏
得分:0 
数比较大的时候用斯特林公式近似求阶乘,
我就是这么做的,不到1s。
2008-09-15 17:45
快速回复:连续奇数乘积的二进制位
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015112 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved