免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: yzc2002
打印 上一主题 下一主题

[算法] 一个算法题,应该有很多种方法可以得到结果 [复制链接]

论坛徽章:
0
21 [报告]
发表于 2006-05-09 17:34 |只看该作者
应该说是只有2,3,5(质因子)的数,本题才有意义,不然的话4=2^2,则4就含有4的因子了。
只有2,3,5(质)因子的数应该只能表示为n=2^x*3^y*5^z(x,y,z为非副整数且x,y,z至少有一个>0),1不符合题意,不能算是解的特例,

论坛徽章:
0
22 [报告]
发表于 2006-05-09 17:37 |只看该作者
应该说是只有2,3,5(质因子)的数,本题才有意义,不然的话4=2^2,则4就含有4的因子了。
只有2,3,5(质)因子的数应该只能表示为n=2^x*3^y*5^z(x,y,z为非副整数且x,y,z至少有一个>0),1不符合题意,不能算是解的特例,
dwtsteven 该用户已被删除
23 [报告]
发表于 2006-05-09 22:44 |只看该作者
提示: 作者被禁止或删除 内容自动屏蔽

论坛徽章:
0
24 [报告]
发表于 2006-05-10 09:04 |只看该作者
一位数据肯定是乘2,3,5之中一位?  4, 6, 9, 呢? 难道满足?

论坛徽章:
0
25 [报告]
发表于 2006-05-10 10:10 |只看该作者
能不能详细解释一下这句话:

通过对和的估计,可以得到C<= exp(三次根号(6*log2*log3*log5*N));取N=1500, 得到C<=4650268755.0

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
26 [报告]
发表于 2006-05-12 16:02 |只看该作者
我把第一种方法进行优化,可以得到O(n)时间、O(1)空间的算法
  1. int i_log(long long m, int n)
  2. {
  3.     int i;
  4.     for(i=0; m >= n; i++) m /= n;
  5.     return i;
  6. }
  7. long long i_pow(int m, int n)
  8. {
  9.     long long val;
  10.     for(val = 1L; n > 0; n--) val *= m;
  11.     return val;
  12. }
  13. long long get_val(int i, int j, int k)
  14. {
  15.     int x;
  16.     int val = 1;
  17.     for(x = 0; x < i; x++) val *= 2;
  18.     for(x = 0; x < j; x++) val *= 3;
  19.     for(x = 0; x < k; x++) val *= 5;
  20.     return val;
  21. }
  22. int count_n(long long m)
  23. {
  24.     int i, j, n = 0, x;
  25.     for(i=0; i<=i_log(m, 2); i++) {
  26.         x = i_log(m/i_pow(2,i), 3);
  27.         for(j=0; j<=x; j++)
  28.             n += i_log(m/i_pow(2,i)/i_pow(3,j), 5) + 1;
  29.     }
  30.     return n;
  31. }
  32. long long get_max_c(long long m)
  33. {
  34.     int i, j, n = 0, x;
  35.     long long c = 0, t;
  36.     for(i=0; i<=i_log(m, 2); i++) {
  37.         x = i_log(m/i_pow(2,i), 3);
  38.         for(j=0; j<=x; j++) {
  39.             t = get_val(i, j, i_log(m/i_pow(2,i)/i_pow(3,j), 5));
  40.             if( t > c) c = t;
  41.         }
  42.     }
  43.     return c;
  44. }
  45. long long get_c(long long max, int n)
  46. {
  47.     int max_n = count_n(max), tmp;
  48.     long long min = 0, mid;
  49.     while(max_n > n) {
  50.         mid = (max + min) / 2;
  51.         if((tmp = count_n(mid)) < n)
  52.             min = mid;
  53.         else {
  54.             max = mid;
  55.             max_n = tmp;
  56.         }
  57.     }
  58.     return get_max_c(max);
  59. }

  60. int main()
  61. {
  62.     printf("%lld\n", get_c(4650268755LL, 1500));
  63. }
复制代码

这个的好处是没用到数组,空间占用小

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
27 [报告]
发表于 2006-05-12 16:18 |只看该作者
原帖由 wxp19831104 于 2006-5-10 10:10 发表
能不能详细解释一下这句话:

通过对和的估计,可以得到C<= exp(三次根号(6*log2*log3*log5*N));取N=1500, 得到C<=4650268755.0

如图:

t.JPG (18.38 KB, 下载次数: 69)

t.JPG

论坛徽章:
0
28 [报告]
发表于 2006-05-12 17:28 |只看该作者
我的想法于你们不一样。可以将i,j,k看做一组数,它对应一个形式为2^i*3^j*5^k的数
即f(i,j,k)=2^i*3^j*5^k.
n    i,j,k
1   0,0,0
2   1,0,0
3   0,1,0
4   2,0,0
5   0,0,1
6   1,1,0
......
只要找出第1500组这样的数就可以了。
用方法找出前一组(或前N组)和后一组的关系即可。

[ 本帖最后由 jakieyoung 于 2006-5-12 17:31 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP