找回密码
 欢迎注册
楼主: liangbch

[讨论] 数组拆分算法

[复制链接]
发表于 2009-2-4 21:55:46 | 显示全部楼层
感觉好难好难。楼上最新进展怎样?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-5 10:51:05 | 显示全部楼层
目前,已经写了多个版本,均不理想,新版本正在编写中。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-5 13:37:27 | 显示全部楼层
恩,这题挺有意思的,但也挺复杂的。我也提供一个思路供大家参考吧! 基本上就是用贪心,以1024个数为例,其实只需要计算513-1024就可以了,前面的1-512,都是后面的约数,不会成为限制条件 找到513-1024中公约数最大的作为一对,并计算其最小公倍数m,然后再从剩余的数里找到同m公约数最大的数q,并计算m同q的最小公倍m1, 以此类推,直到mi > 2^32,然后对剩余的数重复上面的办法,直到所有数都分组完毕。 这种办法看起来效率比较低,但其实有些地方,有很大的优化空间,首先,1024个数的约数范围为1-1024/3,约数最大的一对为1023(341*3)和682(341 * 2),其次的一对为340*2和340*3...... 找到1023和682后,最小公倍为2046,找出2046小于341的最大约数,然后在剩余的数中找到其倍数,就应当是下一个要找的数。然后重新计算2046和该数的最小公倍(应该不用重新算,直接用2046 * 该数 / 约数 就行),再找出小于341的最大约数(这个计算也可以优化),以此类推......
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-5 15:46:51 | 显示全部楼层
22以内的数可分一组 within 22 lcm1=(16*27*25*7*11*13*17*19) =3,491,888,400 42以内的数可分2组 within 42 lcm1=(16*27*25*7*11*13*17*19) =3,491,888,400 lcm2= (23*29*31*32*37*41*3) =3,011,232,864 60以内的数可分3组 within 60 lcm1 (=16*27*25*7*11*13*17*19) lcm2 (=23*29*31*32*37*41*3 ) =3,011,232,864 lcm3 (=43*47*49*53*59*12) =3,715,964,196 78以内的数可分4组 within 78 lcm1= (=16*27*25*7*11*13*17*19)=3,491,888,400 lcm2= (=23*29*31*32*37*41*3 ) =3,011,232,864 lcm3= (=43*47*49*53*59*12) =3,715,964,196 lcm4= (=61*64*67*71*73) =1,355,706,944 100以内的数可分5组 within 100 lcm1= (=16*27*25*7*11*13*17*19)=3,491,888,400 lcm2= (=23*29*31*81*97*4 ) = 649,836,756 lcm3= (=37*64*79*83*89*3) = 4,145,702,592.00 lcm4= (=41*43*47*49*53*2) = 430,380,034 lcm5= (=59*61*67*71*73) = 1,249,792,339.00
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-5 17:29:30 | 显示全部楼层
这个比较难,通用的肯定计算量巨大,就找个特例看看,比如1024 ifactors(factorial(1024))=[1, [[2, 1023], [3, 508], [5, 253], [7, 168], [11, 101], [13, 84], [17, 63], [19, 55], [23, 45], [29, 36], [31, 34], [37, 27], [41, 24], [43, 23], [47, 21], [53, 19], [59, 17], [61, 16], [67, 15], [71, 14], [73, 14], [79, 12], [83, 12], [89, 11], [97, 10], [101, 10], [103, 9], [107, 9], [109, 9], [113, 9], [127, 8], [131, 7], [137, 7], [139, 7], [149, 6], [151, 6], [157, 6], [163, 6], [167, 6], [173, 5], [179, 5], [181, 5], [191, 5], [193, 5], [197, 5], [199, 5], [211, 4], [223, 4], [227, 4], [229, 4], [233, 4], [239, 4], [241, 4], [251, 4], [257, 3], [263, 3], [269, 3], [271, 3], [277, 3], [281, 3], [283, 3], [293, 3], [307, 3], [311, 3], [313, 3], [317, 3], [331, 3], [337, 3], [347, 2], [349, 2], [353, 2], [359, 2], [367, 2], [373, 2], [379, 2], [383, 2], [389, 2], [397, 2], [401, 2], [409, 2], [419, 2], [421, 2], [431, 2], [433, 2], [439, 2], [443, 2], [449, 2], [457, 2], [461, 2], [463, 2], [467, 2], [479, 2], [487, 2], [491, 2], [499, 2], [503, 2], [509, 2], [521, 1], [523, 1], [541, 1], [547, 1], [557, 1], [563, 1], [569, 1], [571, 1], [577, 1], [587, 1], [593, 1], [599, 1], [601, 1], [607, 1], [613, 1], [617, 1], [619, 1], [631, 1], [641, 1], [643, 1], [647, 1], [653, 1], [659, 1], [661, 1], [673, 1], [677, 1], [683, 1], [691, 1], [701, 1], [709, 1], [719, 1], [727, 1], [733, 1], [739, 1], [743, 1], [751, 1], [757, 1], [761, 1], [769, 1], [773, 1], [787, 1], [797, 1], [809, 1], [811, 1], [821, 1], [823, 1], [827, 1], [829, 1], [839, 1], [853, 1], [857, 1], [859, 1], [863, 1], [877, 1], [881, 1], [883, 1], [887, 1], [907, 1], [911, 1], [919, 1], [929, 1], [937, 1], [941, 1], [947, 1], [953, 1], [967, 1], [971, 1], [977, 1], [983, 1], [991, 1], [997, 1], [1009, 1], [1013, 1], [1019, 1], [1021, 1]]] 接下来就看多贪心了 我们假设我们的方案使所有组都是满位(10位10进制),当然这比较难做到。 于是,因子重数为1,2的那些先不管,重数为3的都是些3位数,如果都在一组,有可能给该组公倍数乘2,但不在一组则为另一组减少3位,所以一定放一组 重数为4,5,6的也要放到一组 重数为7的 可能使该组多乘60,而重数为7的都是3位,也合算 重数为8的 就不好说了 于是我们可用分步的贪心: 先将重数为7以上的石头放好,再放那些沙子去调整
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-6 08:36:49 | 显示全部楼层
上面光“大石头”就上百了,况且还要增加如31*31 ,29*29,31*29 ..等“大石头”,看来1024太大了,还是先找个小一点的
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-6 11:40:30 | 显示全部楼层
回无心人,从我的实际应用来讲,n<65536,可用一个WORD类型表示。 这个问题的实际应用。 为方便起见,我做一些简化。 有m个分数,m<=n, 通常m很接近于n. 这些分数全部真分数(分子小于分母),且分母互不相同且小于n,求这些分数的和并精确到R位。 R通常大于100而小于65535。 如果按照通常的做法,复杂度为 m*r, 如果将这些分数分成几组,每一组的各个分数先通分并相加,再做除法则可以提高速度。 当n较大时,实现一个优化的算法比较困看。详细的算法以后再讲,现在先贴出n<223时的分组做法,这个做法是半手工的,但应该是一个接近最佳答案的做法。 下贴出程序运行结果: check numbers within 22 LCM[0]=3491888400, bArray[0]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22, check numbers within 42 LCM[0]=3491888400, bArray[0]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,30,33,34,35,36,38,39,40,42, LCM[1]=3011232864, bArray[1]=23,29,31,32,37,41, check numbers within 62 LCM[0]=3491888400, bArray[0]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,30,33,34,35,36,38,39,40,42,44,45,48,50,51,52,54,55,56,57,60, LCM[1]=3011232864, bArray[1]=23,29,31,32,37,41,46,58, LCM[2]=3715964196, bArray[2]=43,47,49,53,59, check numbers within 78 LCM[0]=3491888400, bArray[0]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,30,33,34,35,36,38,39,40,42,44,45,48,50,51,52,54,55,56,57,60,63,65,66,68,70,72,75,76,77,78, LCM[1]=3011232864, bArray[1]=23,29,31,32,37,41,46,58,62,69,74, LCM[2]=3715964196, bArray[2]=43,47,49,53,59, LCM[3]=2711413888, bArray[3]=61,64,67,71,73, check numbers within 100 LCM[0]=3491888400, bArray[0]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,30,33,34,35,36,38,39,40,42,44,45,48,50,51,52,54,55,56,57,60,63,65,66,68,70,72,75,76,77,78,80,84,85,88,90,91,95,99,100, LCM[1]=2249244060, bArray[1]=23,29,31,37,46,49,58,62,69,74,87,92,93,98, LCM[2]=4215967680, bArray[2]=32,41,43,47,53,64,82,86,94,96, LCM[3]=2773511766, bArray[3]=59,61,67,71,81, LCM[4]=4132280413, bArray[4]=73,79,83,89,97, check numbers within 88 LCM[0]=3491888400, bArray[0]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,30,33,34,35,36,38,39,40,42,44,45,48,50,51,52,54,55,56,57,60,63,65,66,68,70,72,75,76,77,78,80,84,85,88, LCM[1]=1945292160, bArray[1]=23,29,31,32,46,49,58,62,64,69,87, LCM[2]=183951420, bArray[2]=37,41,43,47,74,82,86, LCM[3]=4140735876, bArray[3]=53,59,61,67,81, LCM[4]=203909586, bArray[4]=71,73,79,83, check numbers within 106 LCM[0]=3491888400, bArray[0]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,30,33,34,35,36,38,39,40,42,44,45,48,50,51,52,54,55,56,57,60,63,65,66,68,70,72,75,76,77,78,80,84,85,88,90,91,95,99,100,102,104,105, LCM[1]=1945292160, bArray[1]=23,29,31,32,46,49,58,62,64,69,87,92,93,96,98, LCM[2]=183951420, bArray[2]=37,41,43,47,74,82,86,94, LCM[3]=4140735876, bArray[3]=53,59,61,67,81,106, LCM[4]=203909586, bArray[4]=71,73,79,83, LCM[5]=179618198, bArray[5]=89,97,101,103, check numbers within 124 LCM[0]=3491888400, bArray[0]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,30,33,34,35,36,38,39,40,42,44,45,48,50,51,52,54,55,56,57,60,63,65,66,68,70,72,75,76,77,78,80,84,85,88,90,91,95,99,100,102,104,105,108,110,112,114,117,119,120, LCM[1]=1945292160, bArray[1]=23,29,31,32,46,49,58,62,64,69,87,92,93,96,98,115,116,124, LCM[2]=183951420, bArray[2]=37,41,43,47,74,82,86,94,111,123, LCM[3]=4140735876, bArray[3]=53,59,61,67,81,106,118,122, LCM[4]=203909586, bArray[4]=71,73,79,83, LCM[5]=179618198, bArray[5]=89,97,101,103, LCM[6]=318936398, bArray[6]=107,109,113,121, check numbers within 138 LCM[0]=3491888400, bArray[0]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,30,33,34,35,36,38,39,40,42,44,45,48,50,51,52,54,55,56,57,60,63,65,66,68,70,72,75,76,77,78,80,84,85,88,90,91,95,99,100,102,104,105,108,110,112,114,117,119,120,126,130,132,133,135,136, LCM[1]=1945292160, bArray[1]=23,29,31,32,46,49,58,62,64,69,87,92,93,96,98,115,116,124,128,138, LCM[2]=183951420, bArray[2]=37,41,43,47,74,82,86,94,111,123,129, LCM[3]=4140735876, bArray[3]=53,59,61,67,81,106,118,122,134, LCM[4]=203909586, bArray[4]=71,73,79,83, LCM[5]=179618198, bArray[5]=89,97,101,103, LCM[6]=318936398, bArray[6]=107,109,113,121, LCM[7]=284908625, bArray[7]=125,127,131,137, check numbers within 162 LCM[0]=3491888400, bArray[0]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,30,33,34,35,36,38,39,40,42,44,45,48,50,51,52,54,55,56,57,60,63,65,66,68,70,72,75,76,77,78,80,84,85,88,90,91,95,99,100,102,104,105,108,110,112,114,117,119,120,126,130,132,133,135,136,140,143,144,150,152,153,154,156, LCM[1]=1945292160, bArray[1]=23,29,31,32,46,49,58,62,64,69,87,92,93,96,98,115,116,124,128,138,145,147,155,160,161, LCM[2]=183951420, bArray[2]=37,41,43,47,74,82,86,94,111,123,129,141,148, LCM[3]=4140735876, bArray[3]=53,59,61,67,81,106,118,122,134,159,162, LCM[4]=203909586, bArray[4]=71,73,79,83,142,146,158, LCM[5]=179618198, bArray[5]=89,97,101,103, LCM[6]=318936398, bArray[6]=107,109,113,121, LCM[7]=284908625, bArray[7]=125,127,131,137, LCM[8]=490995677, bArray[8]=139,149,151,157, check numbers within 178 LCM[0]=3491888400, bArray[0]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,30,33,34,35,36,38,39,40,42,44,45,48,50,51,52,54,55,56,57,60,63,65,66,68,70,72,75,76,77,78,80,84,85,88,90,91,95,99,100,102,104,105,108,110,112,114,117,119,120,126,130,132,133,135,136,140,143,144,150,152,153,154,156,165,168,170,171,175,176, LCM[1]=1945292160, bArray[1]=23,29,31,32,46,49,58,62,64,69,87,92,93,96,98,115,116,124,128,138,145,147,155,160,161,174, LCM[2]=183951420, bArray[2]=37,41,43,47,74,82,86,94,111,123,129,141,148,164,172, LCM[3]=4140735876, bArray[3]=53,59,61,67,81,106,118,122,134,159,162,177, LCM[4]=203909586, bArray[4]=71,73,79,83,142,146,158,166, LCM[5]=179618198, bArray[5]=89,97,101,103,178, LCM[6]=318936398, bArray[6]=107,109,113,121, LCM[7]=284908625, bArray[7]=125,127,131,137, LCM[8]=490995677, bArray[8]=139,149,151,157, LCM[9]=795860377, bArray[9]=163,167,169,173, check numbers within 196 LCM[0]=3491888400, bArray[0]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,30,33,34,35,36,38,39,40,42,44,45,48,50,51,52,54,55,56,57,60,63,65,66,68,70,72,75,76,77,78,80,84,85,88,90,91,95,99,100,102,104,105,108,110,112,114,117,119,120,126,130,132,133,135,136,140,143,144,150,152,153,154,156,165,168,170,171,175,176,180,182,187,189,190,195, LCM[1]=1945292160, bArray[1]=23,29,31,32,46,49,58,62,64,69,87,92,93,96,98,115,116,124,128,138,145,147,155,160,161,174,184,186,192,196, LCM[2]=183951420, bArray[2]=37,41,43,47,74,82,86,94,111,123,129,141,148,164,172,185,188, LCM[3]=4140735876, bArray[3]=53,59,61,67,81,106,118,122,134,159,162,177,183, LCM[4]=203909586, bArray[4]=71,73,79,83,142,146,158,166, LCM[5]=179618198, bArray[5]=89,97,101,103,178,194, LCM[6]=318936398, bArray[6]=107,109,113,121, LCM[7]=284908625, bArray[7]=125,127,131,137, LCM[8]=490995677, bArray[8]=139,149,151,157, LCM[9]=795860377, bArray[9]=163,167,169,173, LCM[10]=1194324337, bArray[10]=179,181,191,193, check numbers within 222 LCM[0]=3491888400, bArray[0]=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,24,25,26,27,28,30,33,34,35,36,38,39,40,42,44,45,48,50,51,52,54,55,56,57,60,63,65,66,68,70,72,75,76,77,78,80,84,85,88,90,91,95,99,100,102,104,105,108,110,112,114,117,119,120,126,130,132,133,135,136,140,143,144,150,152,153,154,156,165,168,170,171,175,176,180,182,187,189,190,195,198,200,204,208,209,210,216,220,221, LCM[1]=1945292160, bArray[1]=23,29,31,32,46,49,58,62,64,69,87,92,93,96,98,115,116,124,128,138,145,147,155,160,161,174,184,186,192,196,203,217, LCM[2]=183951420, bArray[2]=37,41,43,47,74,82,86,94,111,123,129,141,148,164,172,185,188,205,215,222, LCM[3]=4140735876, bArray[3]=53,59,61,67,81,106,118,122,134,159,162,177,183,201,212, LCM[4]=203909586, bArray[4]=71,73,79,83,142,146,158,166,213,219, LCM[5]=179618198, bArray[5]=89,97,101,103,178,194,202,206, LCM[6]=318936398, bArray[6]=107,109,113,121,214,218, LCM[7]=284908625, bArray[7]=125,127,131,137, LCM[8]=490995677, bArray[8]=139,149,151,157, LCM[9]=795860377, bArray[9]=163,167,169,173, LCM[10]=1194324337, bArray[10]=179,181,191,193, LCM[11]=1712269431, bArray[11]=197,199,207,211, 再给出代码:
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <memory.h>
  4. typedef unsigned short WORD;
  5. typedef unsigned long DWORD;
  6. /*
  7. 22以内的数可分一组
  8. lcm1=(16*27*25*7*11*13*17*19) =3,491,888,400
  9. 42以内的数可分2组
  10. lcm1=(16*27*25*7*11*13*17*19) =3,491,888,400
  11. lcm2= (23*29*31*32*37*41*3) =3,011,232,864
  12. 60以内的数可分3组
  13. lcm1 (=16*27*25*7*11*13*17*19) =3,491,888,400
  14. lcm2 (=23*29*31*32*37*41*3 ) =3,011,232,864
  15. lcm3 (=43*47*49*53*59*12) =3,715,964,196
  16. 78以内的数可分4组
  17. lcm1= (=16*27*25*7*11*13*17*19)=3,491,888,400
  18. lcm2= (=23*29*31*32*37*41*3 ) =3,011,232,864
  19. lcm3= (=43*47*49*53*59*12) =3,715,964,196
  20. lcm4= (=61*64*67*71*73*3) =2,711,413,888
  21. 100以内的数可分5组
  22. lcm1 =16*27*25*7*11*13*17*19 =3,491,888,400
  23. lcm2 =23*29*31*37*49*3*4*5 =2,249,244,060
  24. lcm3 =41*43*47*53*64*3*5 =4,215,967,680
  25. lcm4 =59*61*67*81*71*2 =2,773,511,766
  26. lcm5 =73*79*83*89*97 =4,132,280,413
  27. 226以内的数可分12组
  28. lcm1 =16*27*25*7*11*13*17*19 =3,491,888,400 (up to 22)
  29. lcm2 =23*29*31*128*49*3*5 =1,945,292,160 (up to 36)
  30. lcm3 =37*41*43*47*4*3*5 =183,951,420 (up to 52)
  31. lcm4 =53*59*61*67*81*4 =4140735876 (up to 70)
  32. lcm5 =71*73*79*83*3*2 =203,909,586 (up to 88)
  33. lcm6 =89*97*101*103*2 =179,618,198 (up to 106)
  34. lcm7 =107*109*113*121*2 =318,936,398 (up to 124)
  35. lcm8 =125*127*131*137 =284,908,625 (up to 138)
  36. lcm9 =139*149*151*157 =490,995,677 (up to 162)
  37. lcm10=163*167*169*173 =795,860,377 (up to 178)
  38. lcm11=179*181*191*193 =1,194,324,337 (up to 196)
  39. lcm12=197*199*207*211 =1712269431 (up to 222)
  40. */
  41. void verifySplitArray(WORD n, const DWORD lcmArray[],int len)
  42. {
  43. WORD *pBuff=new WORD[n];
  44. int i,j,c1,c2;
  45. for (i=1;i<=n;i++)
  46. pBuff[i-1]=i;
  47. c1=n;
  48. for (j=0;j<len;j++)
  49. {
  50. printf("\nLCM[%d]=%u,bArray[%d]=",j,lcmArray[j],j);
  51. for (c2=0,i=0;i<c1;i++)
  52. {
  53. if (lcmArray[j] % pBuff[i]==0)
  54. {
  55. printf("%hu,",pBuff[i]);
  56. }
  57. else
  58. {
  59. pBuff[c2++]=pBuff[i];
  60. }
  61. }
  62. c1=c2;
  63. }
  64. if (c1>0)
  65. {
  66. printf("\nThe following is unsort:\n");
  67. for (i=0;i<c1;i++)
  68. {
  69. printf("%hu,",pBuff[i]);
  70. }
  71. }
  72. delete[] pBuff;
  73. }
  74. void verifyAll()
  75. {
  76. const DWORD lcmArray22[]={3491888400};
  77. const DWORD lcmArray42[]={3491888400,3011232864};
  78. const DWORD lcmArray60[]={3491888400, 3011232864,3715964196};
  79. const DWORD lcmArray78[]={3491888400, 3011232864, 3715964196, 2711413888};
  80. const DWORD lcmArray100[]={3491888400,2249244060,4215967680, 2773511766,4132280413};
  81. const DWORD lcmArray222[]=
  82. {
  83. 3491888400,1945292160 ,183951420,4140735876,
  84. 203909586,179618198,318936398,284908625,
  85. 490995677,795860377,1194324337,1712269431
  86. };
  87. printf("\n\ncheck numbers within %d\n",22);
  88. verifySplitArray(22,lcmArray22,sizeof(lcmArray22)/sizeof(DWORD));
  89. printf("\n\ncheck numbers within %d\n",42);
  90. verifySplitArray(42,lcmArray42,sizeof(lcmArray42)/sizeof(DWORD));
  91. printf("\n\ncheck numbers within %d\n",62);
  92. verifySplitArray(60,lcmArray60,sizeof(lcmArray60)/sizeof(DWORD));
  93. printf("\n\ncheck numbers within %d\n",78);
  94. verifySplitArray(78,lcmArray78,sizeof(lcmArray78)/sizeof(DWORD));
  95. printf("\n\ncheck numbers within %d\n",100);
  96. verifySplitArray(100,lcmArray100,sizeof(lcmArray100)/sizeof(DWORD));
  97. //-------------------------------------------------
  98. printf("\n\ncheck numbers within %d\n",88);
  99. verifySplitArray(88,lcmArray222,5);
  100. printf("\n\ncheck numbers within %d\n",106);
  101. verifySplitArray(106,lcmArray222,6);
  102. printf("\n\ncheck numbers within %d\n",124);
  103. verifySplitArray(124,lcmArray222,7);
  104. printf("\n\ncheck numbers within %d\n",138);
  105. verifySplitArray(138,lcmArray222,8);
  106. printf("\n\ncheck numbers within %d\n",162);
  107. verifySplitArray(162,lcmArray222,9);
  108. printf("\n\ncheck numbers within %d\n",178);
  109. verifySplitArray(178,lcmArray222,10);
  110. printf("\n\ncheck numbers within %d\n",196);
  111. verifySplitArray(196,lcmArray222,11);
  112. printf("\n\ncheck numbers within %d\n",222);
  113. verifySplitArray(222,lcmArray222,12);
  114. }
  115. int main(int argc, char* argv[])
  116. {
  117. verifyAll();
  118. return 0;
  119. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-2-6 11:50:47 | 显示全部楼层
如 27 # medie2005 那样,用2进制 可以分析的更多一些 对于重数为8的因子,如 [127, 8] 分别对应127* 1 - 127*8 乘1,2,3,4显然不用考虑 *5,6,7,8 这4个数,因为127是7位2进制,如果6和8在一组,只给这组增加了2位(乘了3),所以放在一起比较核算 但假如5,6,7这几个数在同一组中而 127*8的这组又不包含3,5,7这几个因子的话, 那么 127*5,127*6,127*7这几个数放在哪组都给该组增加7位 。 但由于上述条件很苛刻,所以倾向于将所有127的倍数都放在一组
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-6 12:02:11 | 显示全部楼层
对于重数为8的因子,如 [127, 8] 分别对应127* 1 - 127*8 乘1,2,3,4显然不用考虑 *5,6,7,8 这4个数,因为127是7位2进制,如果6和8在一组,只给这组增加了2位(乘了3),所以放在一起比较核算
不明白你的意思,127*1 到 127*4 的最小公倍数是 127*3*4 不明白你的意思,127*1 到 127*8 的最小公倍数是 127*8*3*5*7
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2009-2-6 12:24:18 | 显示全部楼层
我的分组的基本原则。 第2种方法: 1. 任何一个自然数都可以写成几个质数乘积的乘积。 2. 对n以内所有的数按照质因数的大小排序,首先按照最大质因数排序升序排列,最大质因数相同者按照次大质因数排序,以此类推。 3. 从排序后数组中依次取数,直到这几个数的最小公倍数小于2^32, 将这些数分到一组。 4。重复步骤3,直到数组取空。 例如对16以内的数,排序后将使这个样子 2=2 4=2*2 8=2*2*2 16=2*2*2*2 3=3 6=3*2 12=3*2*2 9=3*3 5=5 10=5*2 15=5*3 7=7 14=7*2 11=11 13=13 14=14 15=15 对于127*1 到 127*8 排序后将是 127 127*2 127*4 127*8 127*3 127*6 127*5 127*7 第3种方法: 1. 任何一个自然数都可以写成几个质数幂的乘积。 2. 对n以内所有的数按照质数幂因子的大小排序,首先按照最大质数幂因子排序升序排列,最大质数幂因子相同者按照次大质数幂因子排序,以此类推。 3. 从排序后数组中依次取数,直到这几个数的最小公倍数小于2^32, 将这些数分到一组。 4。重复步骤3,直到数组取空。 2=2 3=3 6=3*2 4=4 12=4*3 5=5 10=5*2 15=5*3 7=7 14=7*2 8=8 9=9 11=11 13=13 16=16 我倾向于第3个方法。 当然,这只是基本原则,在实际算法实现中,采用了更多的规则,以实现分组最优。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-11-22 13:07 , Processed in 0.026405 second(s), 14 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表