回复 9楼 逢考必过阿俊
我只是这么一说,只能可能有规律。但既然你说了,我就写段代码试试,发现没规律代码没验证,写得也很烂,只是为了验证有没有规律
程序代码:
#include <stdio.h> #include <stdlib.h> typedef unsigned long long ST; ST bar( unsigned p, unsigned n9, unsigned n8, unsigned n7, unsigned n6, unsigned n5, unsigned n4, unsigned n3, unsigned n2, unsigned n1 ) { static const unsigned primes[25] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97 }; static unsigned table[100][25] = { 1 }; if( table[0][0] == 1 ) { table[0][0] = 0; for( unsigned r=0; r!=100; ++r ) { unsigned t = r; for( unsigned i=0; i!=25 && t!=0; ) { if( t%primes[i] == 0 ) { t /= primes[i]; ++table[r][i]; } else ++i; } } for( unsigned r=1; r!=100; ++r ) { for( unsigned i=0; i!=25; ++i ) table[r][i] += table[r-1][i]; } } // p! / n9! / n8! / …… / n0! unsigned n0 = p - n9 - n8 - n7 - n6 - n5 - n4 - n3 - n2 - n1; unsigned row[25] = { 0 }; for( unsigned i=0; i!=25; ++i ) row[i] = table[p][i]-table[n9][i]-table[n8][i]-table[n7][i]-table[n6][i]-table[n5][i]-table[n4][i]-table[n3][i]-table[n2][i]-table[n1][i]-table[n0][i]; ST result = 1; for( unsigned i=0; i!=25; ++i ) { for( unsigned j=0; j!=row[i]; ++j ) { if( result*primes[i]/result!=primes[i] ) { puts( "--- overflow ---" ); exit(1); } result *= primes[i]; } } return result; } ST foo( unsigned n ) { ST result = 0; // n位整数,各位之和最大为9n,也就是前缀在[1,9n]范围内 for( unsigned pre=1; pre<=9*n; ++pre ) { const unsigned p = 1 + (pre>=10) + (pre>=100); // pre一共有几位 const unsigned r = n-p; // 剩余的位数 const unsigned s = pre - pre/1%10 - pre/10%10 - pre/100%10; // 剩余的位数 的各位和 if( s > r*9 ) break; // 现在要求 剩余的位数的各位之和s 等于 前缀的值pre - 前缀的各位之和 // 例如 23981(前缀23),(9+8+1) == 23 - (2+3) // 设 剩余的位数 有a个9,b个8,c个7,……(a+b+c+…<=r && 9a+8b+7c+…==s) for( unsigned a=0; a<=r && a*9<=s; ++a ) for( unsigned b=0; a+b<=r && a*9+b*8<=s; ++b ) for( unsigned c=0; a+b+c<=r && a*9+b*8+c*7<=s; ++c ) for( unsigned d=0; a+b+c+d<=r && a*9+b*8+c*7+d*6<=s; ++d ) for( unsigned e=0; a+b+c+d+e<=r && a*9+b*8+c*7+d*6+e*5<=s; ++e ) for( unsigned f=0; a+b+c+d+e+f<=r && a*9+b*8+c*7+d*6+e*5+f*4<=s; ++f ) for( unsigned g=0; a+b+c+d+e+f+g<=r && a*9+b*8+c*7+d*6+e*5+f*4+g*3<=s; ++g ) for( unsigned h=0; a+b+c+d+e+f+g+h<=r && a*9+b*8+c*7+d*6+e*5+f*4+g*3+h*2<=s; ++h ) { const unsigned i_max = r-a-b-c-d-e-f-g-h; const unsigned i = s-a*9-b*8-c*7-d*6-e*5-f*4-g*3-h*2; if( i <= i_max ) { ST the = bar( r, a,b,c,d,e,f,g,h,i ); if( result+the<result ) { puts( "--- overflow ---" ); exit(1); } result += the; } } } return result; } int main( void ) { for( unsigned n=1; n<=100; ++n ) printf( "f(%u) = %llu\n", n, foo(n) ); }
输出是
f(1) = 9 // 这个还要加1,因为0也是1位数
f(2) = 9
f(3) = 19
f(4) = 119
f(5) = 1119
f(6) = 11119
f(7) = 111119
f(8) = 1111119
f(9) = 11111119
f(10) = 111111119
f(11) = 1111111119
f(12) = 11111111109 // 这里就没规律了,不知道是真如此,还是我代码有bug
f(13) = 111110187329
f(14) = 1110772528459
f(15) = 11077860489819
f(16) = 109455801519569
f(17) = 1057665543096469
f(18) = 9838457914487439
f(19) = 86933146186369559
f(20) = 724511714337673129
f(21) = 5699633355881508969
--- overflow ---
f(2) = 9
f(3) = 19
f(4) = 119
f(5) = 1119
f(6) = 11119
f(7) = 111119
f(8) = 1111119
f(9) = 11111119
f(10) = 111111119
f(11) = 1111111119
f(12) = 11111111109 // 这里就没规律了,不知道是真如此,还是我代码有bug
f(13) = 111110187329
f(14) = 1110772528459
f(15) = 11077860489819
f(16) = 109455801519569
f(17) = 1057665543096469
f(18) = 9838457914487439
f(19) = 86933146186369559
f(20) = 724511714337673129
f(21) = 5699633355881508969
--- overflow ---