很长的一道题目,说的是一个贪心减法的问题:对于一个M/N的分数,我们希望能够把它写成多个1/D相加的形式,并且每个D都要尽可能的大,不能超过1000000。题目已经说明要使用long long了,另外的话就按照贪心算法的一般思路去进行即可,无陷阱。
Run Time: 0.29sec
Run Memory: 304KB
Code Length: 1358Bytes
SubmitTime: 2012-03-02 12:58:39
// Problem#: 2409
// Submission#: 1229318
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <vector>
#include <stack>
using namespace std;
struct Fraction {
long long a, b;
void set( long long x, long long y ) { a = x; b = y; }
void subtract( const Fraction& f ) {
a = a * f.b - b * f.a;
b = b * f.b;
long long m = a, n = b, temp;
while ( m != 0 ) {
temp = m;
m = n % m;
n = temp;
}
a /= n;
b /= n;
}
};
int main()
{
long long M, N;
Fraction target, sub;
while ( scanf( "%lld%lld", &M, &N ) && M && N ) {
stack<Fraction> s;
vector<Fraction> v;
target.set( M, N );
while ( !( target.a == 1 && target.b <= 1000000 ) ) {
if ( target.b <= 1000000 ) {
s.push( target );
sub.set( 1, target.b / target.a + 1 );
v.push_back( sub );
target.subtract( sub );
}
else {
target = s.top();
sub.set( 1, v.back().b + 1 );
v.pop_back();
v.push_back( sub );
target.subtract( sub );
}
}
v.push_back( target );
printf( "%lld", v[ 0 ].b );
for ( int i = 1; i < v.size(); i++ )
printf( " %lld", v[ i ].b );
printf( "\n" );
}
return 0;
}