算法的思路:假设有i9个9,i8个8,i7个7……
编码的难点:大数计算
程序代码:
#include <utility>
#include <iostream>
#include <iomanip>
struct Type
{
Type( unsigned h, unsigned m, unsigned l ) : high(h), middle(m), low(l)
{
}
Type( unsigned m, unsigned l ) : high(0), middle(m), low(l)
{
}
Type( unsigned l ) : high(0), middle(0), low(l)
{
}
Type& operator+=( const Type& type )
{
low += type.low;
unsigned carry = low/10000000;
low%=10000000;
middle += type.middle + carry;
carry = middle/10000000;
middle %= 10000000;
high += type.high + carry;
return *this;
}
Type operator+( const Type& type ) const
{
Type ret = *this;
ret += type;
return ret;
}
Type& operator-=( const Type& type )
{
low = 10000000 + low - type.low;
unsigned carry = low/10000000;
low%=10000000;
middle = 10000000 + middle + carry - 1 - type.middle;
carry = middle/10000000;
middle %= 10000000;
high = high + carry - 1 - type.high;
return *this;
}
Type operator-( const Type& type ) const
{
Type ret = *this;
ret -= type;
return ret;
}
Type& operator*=( unsigned n )
{
unsigned long long tmp = 1ull*low*n;
unsigned long long carry = tmp/10000000;
low = unsigned(tmp%10000000);
tmp = 1ull*middle*n + carry;
carry = tmp/10000000;
middle = unsigned(tmp%10000000);
high = unsigned(high*n + carry);
return *this;
}
Type operator*( unsigned n ) const
{
Type ret = *this;
ret *= n;
return ret;
}
bool operator>( const Type& type ) const
{
if( high > type.high )
return true;
if( high < type.high )
return false;
if( middle > type.middle )
return true;
if( middle < type.middle )
return false;
return low>type.low;
}
bool operator>=( const Type& type ) const
{
if( high > type.high )
return true;
if( high < type.high )
return false;
if( middle > type.middle )
return true;
if( middle < type.middle )
return false;
return low>=type.low;
}
unsigned high, middle, low;
};
std::ostream& operator<<( std::ostream& os, const Type& type )
{
return os << std::setfill('0') << std::setw(7) << type.high
<< std::setfill('0') << std::setw(7) << type.middle
<< std::setfill('0') << std::setw(7) << type.low;
}
const Type C[10] = { Type( 0 )
, Type( 1 )
, Type( 2097152 )
, Type( 1046, 353203 )
, Type( 439804, 6511104 )
, Type( 4, 7683715, 8203125 )
, Type( 219, 3695064, 377856 )
, Type( 5585, 4586408, 3284007 )
, Type( 92233, 7203685, 4775808 )
, Type( 1094189, 8913151, 2359209 ) };
const Type minval = Type( 1000000, 0000000, 0000000 );
const Type maxval = Type( 9999999, 9999999, 9999999 );
// a*num^21>=minv && b*num^21>maxv && a<=residue && b<=residue+1
std::pair<unsigned,unsigned> foo( const Type& minv, const Type& maxv, unsigned num, unsigned residue )
{
unsigned a=residue+1, b=residue+1;
for( unsigned i=0; i<=residue+1; ++i )
{
Type val = C[num]*i;
if( a==residue+1 && val>=minv )
a = i;
if( val > maxv )
{
b = i;
break;
}
}
return std::pair<unsigned,unsigned>(a,b);
}
// 验证
bool bar( const Type& type, unsigned i9, unsigned i8, unsigned i7, unsigned i6, unsigned i5, unsigned i4, unsigned i3, unsigned i2, unsigned i1 )
{
unsigned t[3] = { type.low, type.middle, type.high };
unsigned m[10] = { 0, i1, i2, i3, i4, i5, i6, i7, i8, i9 };
for( unsigned i=0; i!=3; ++i )
{
--m[ t[i]/1%10 ];
--m[ t[i]/10%10 ];
--m[ t[i]/100%10 ];
--m[ t[i]/1000%10 ];
--m[ t[i]/10000%10 ];
--m[ t[i]/100000%10 ];
--m[ t[i]/1000000%10 ];
}
for( unsigned i=1; i<10; ++i )
if( m[i] != 0 )
return false;
return true;
}
int main()
{
Type l9 = maxval;
std::pair<unsigned,unsigned> r9 = foo( minval, l9, 9, 21 );
for( unsigned i9=r9.first; i9<r9.second; ++i9 )
{
Type l8 = l9 - C[9]*i9;
std::pair<unsigned,unsigned> r8 = foo( 0, l8, 8, 21-i9 );
for( unsigned i8=r8.first; i8<r8.second; ++i8 )
{
Type l7 = l8 - C[8]*i8;
std::pair<unsigned,unsigned> r7 = foo( 0, l7, 7, 21-i9-i8 );
for( unsigned i7=r7.first; i7<r7.second; ++i7 )
{
Type l6 = l7 - C[7]*i7;
std::pair<unsigned,unsigned> r6 = foo( 0, l6, 6, 21-i9-i8-i7 );
for( unsigned i6=r6.first; i6<r6.second; ++i6 )
{
Type l5 = l6 - C[6]*i6;
std::pair<unsigned,unsigned> r5 = foo( 0, l5, 5, 21-i9-i8-i7-i6 );
for( unsigned i5=r5.first; i5<r5.second; ++i5 )
{
Type l4 = l5 - C[5]*i5;
std::pair<unsigned,unsigned> r4 = foo( 0, l4, 4, 21-i9-i8-i7-i6-i5 );
for( unsigned i4=r4.first; i4<r4.second; ++i4 )
{
Type l3 = l4 - C[4]*i4;
std::pair<unsigned,unsigned> r3 = foo( 0, l3, 3, 21-i9-i8-i7-i6-i5-i4 );
for( unsigned i3=r3.first; i3<r3.second; ++i3 )
{
Type l2 = l3 - C[3]*i3;
std::pair<unsigned,unsigned> r2 = foo( 0, l2, 2, 21-i9-i8-i7-i6-i5-i4-i3 );
for( unsigned i2=r2.first; i2<r2.second; ++i2 )
{
Type l1 = l2 - C[2]*i2;
std::pair<unsigned,unsigned> r1 = foo( 0, l1, 1, 21-i9-i8-i7-i6-i5-i4-i3-i2 );
for( unsigned i1=r1.first; i1<r1.second; ++i1 )
{
Type l0 = l1-C[1]*i1;
Type val = maxval - l0;
if( bar(val,i9,i8,i7,i6,i5,i4,i3,i2,i1) )
{
// 未必是从小到大排序
std::cout << val << std::endl;
}
}
}
}
}
}
}
}
}
}
return 0;
}
//449177399146038697307
//128468643043731391252