回无心人,从我的实际应用来讲,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,
再给出代码:- #include <stdio.h>
- #include <stdlib.h>
- #include <memory.h>
-
- typedef unsigned short WORD;
- typedef unsigned long DWORD;
-
- /*
- 22以内的数可分一组
- lcm1=(16*27*25*7*11*13*17*19) =3,491,888,400
-
- 42以内的数可分2组
- 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组
- 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
-
- 78以内的数可分4组
- 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*3) =2,711,413,888
-
-
- 100以内的数可分5组
- lcm1 =16*27*25*7*11*13*17*19 =3,491,888,400
- lcm2 =23*29*31*37*49*3*4*5 =2,249,244,060
- lcm3 =41*43*47*53*64*3*5 =4,215,967,680
- lcm4 =59*61*67*81*71*2 =2,773,511,766
- lcm5 =73*79*83*89*97 =4,132,280,413
-
- 226以内的数可分12组
- lcm1 =16*27*25*7*11*13*17*19 =3,491,888,400 (up to 22)
- lcm2 =23*29*31*128*49*3*5 =1,945,292,160 (up to 36)
- lcm3 =37*41*43*47*4*3*5 =183,951,420 (up to 52)
- lcm4 =53*59*61*67*81*4 =4140735876 (up to 70)
- lcm5 =71*73*79*83*3*2 =203,909,586 (up to 88)
- lcm6 =89*97*101*103*2 =179,618,198 (up to 106)
- lcm7 =107*109*113*121*2 =318,936,398 (up to 124)
- lcm8 =125*127*131*137 =284,908,625 (up to 138)
- lcm9 =139*149*151*157 =490,995,677 (up to 162)
- lcm10=163*167*169*173 =795,860,377 (up to 178)
- lcm11=179*181*191*193 =1,194,324,337 (up to 196)
- lcm12=197*199*207*211 =1712269431 (up to 222)
- */
-
- void verifySplitArray(WORD n, const DWORD lcmArray[],int len)
- {
- WORD *pBuff=new WORD[n];
- int i,j,c1,c2;
- for (i=1;i<=n;i++)
- pBuff[i-1]=i;
-
- c1=n;
- for (j=0;j<len;j++)
- {
- printf("\nLCM[%d]=%u,bArray[%d]=",j,lcmArray[j],j);
- for (c2=0,i=0;i<c1;i++)
- {
- if (lcmArray[j] % pBuff[i]==0)
- {
- printf("%hu,",pBuff[i]);
- }
- else
- {
- pBuff[c2++]=pBuff[i];
- }
- }
- c1=c2;
- }
- if (c1>0)
- {
- printf("\nThe following is unsort:\n");
- for (i=0;i<c1;i++)
- {
- printf("%hu,",pBuff[i]);
- }
- }
- delete[] pBuff;
- }
-
- void verifyAll()
- {
- const DWORD lcmArray22[]={3491888400};
- const DWORD lcmArray42[]={3491888400,3011232864};
- const DWORD lcmArray60[]={3491888400, 3011232864,3715964196};
- const DWORD lcmArray78[]={3491888400, 3011232864, 3715964196, 2711413888};
- const DWORD lcmArray100[]={3491888400,2249244060,4215967680, 2773511766,4132280413};
- const DWORD lcmArray222[]=
- {
- 3491888400,1945292160 ,183951420,4140735876,
- 203909586,179618198,318936398,284908625,
- 490995677,795860377,1194324337,1712269431
- };
-
- printf("\n\ncheck numbers within %d\n",22);
- verifySplitArray(22,lcmArray22,sizeof(lcmArray22)/sizeof(DWORD));
-
-
- printf("\n\ncheck numbers within %d\n",42);
- verifySplitArray(42,lcmArray42,sizeof(lcmArray42)/sizeof(DWORD));
-
-
- printf("\n\ncheck numbers within %d\n",62);
- verifySplitArray(60,lcmArray60,sizeof(lcmArray60)/sizeof(DWORD));
-
-
- printf("\n\ncheck numbers within %d\n",78);
- verifySplitArray(78,lcmArray78,sizeof(lcmArray78)/sizeof(DWORD));
-
- printf("\n\ncheck numbers within %d\n",100);
- verifySplitArray(100,lcmArray100,sizeof(lcmArray100)/sizeof(DWORD));
-
- //-------------------------------------------------
- printf("\n\ncheck numbers within %d\n",88);
- verifySplitArray(88,lcmArray222,5);
-
- printf("\n\ncheck numbers within %d\n",106);
- verifySplitArray(106,lcmArray222,6);
-
- printf("\n\ncheck numbers within %d\n",124);
- verifySplitArray(124,lcmArray222,7);
-
- printf("\n\ncheck numbers within %d\n",138);
- verifySplitArray(138,lcmArray222,8);
-
- printf("\n\ncheck numbers within %d\n",162);
- verifySplitArray(162,lcmArray222,9);
-
- printf("\n\ncheck numbers within %d\n",178);
- verifySplitArray(178,lcmArray222,10);
-
- printf("\n\ncheck numbers within %d\n",196);
- verifySplitArray(196,lcmArray222,11);
-
- printf("\n\ncheck numbers within %d\n",222);
- verifySplitArray(222,lcmArray222,12);
- }
-
- int main(int argc, char* argv[])
- {
- verifyAll();
- return 0;
- }
复制代码 |