埃及分数
在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数。 如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的。 对于一个分数a/b,表示方法有很多种,但是哪种最好呢? 首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越好。 如:
19/45=1/3 + 1/12 + 1/180
19/45=1/3 + 1/15 + 1/45
19/45=1/3 + 1/18 + 1/30,
19/45=1/4 + 1/6 + 1/180
19/45=1/5 + 1/6 + 1/18.
最好的是最后一种,因为1/18比1/180,1/45,1/30,1/180都大。
程序代码:
#include<iostream> using namespace std; class fra //分数结构 { public: fra(); fra(int,int); ~fra(){} void show(); int x(); int y(); bool check(); fra operator + (fra&); fra operator ++ (); fra operator - (fra&); fra operator / (int); fra& operator = (fra&); bool operator == (fra&); bool operator > (fra&); bool operator >= (fra&); private: int xx; int yy; }; static fra F[10]; //保存埃及分数 static int N; //埃及分数长度 static int end; //埃及分数末尾 int main() { bool find(fra,fra,int); int i=0,n,a,b; cin>>a>>b; fra A(1,1),T(a,b); for(n=1;n<15;n++) { N=end=n; if(find(A,T,n)) break; } T.show(); cout<<"="; for(i=1;i<=n;i++) { F[i].show(); if(i!=n) cout<<"+"; } } bool find(fra A,fra T,int i) //埃及分数最佳方案核心 { if(i==1) { if(A==T) return false; if(T.check()&&T>F[end]) { N=end; F[N]=T; N--; return true; } return false; } fra B,C,D; B=T/i; D=++A; while(true) { if(D>=B&&T>D) { C=T-D; if(find(D,C,i-1)) //递归,找到一组方案 { F[N]=D; while(++D>=B) { C=T-D; if(find(D,C,i-1)) //递归,找到最佳方案 F[N]=D; } N--; return true; } } ++D; if(B>D) return false; } } int gcd(int x,int y) //最大公约数 { int temp; x=x<0?-x:x; y=y<0?-y:y; while(y%x!=0) { temp=x; x=y%x; y=temp; } return x; } /*fra类 成员函数*/ void fra::show() { cout<<xx<<"/"<<yy; } int fra::x() { return xx; } int fra::y() { return yy; } bool fra::check() { if(xx==1) return true; return false; } fra::fra() { xx=0; yy=1; } fra::fra(int x=1,int y=2) { int temp=gcd(x,y); if(y<0) { y=-y; x=-x; } xx=x/temp; yy=y/temp; } fra fra::operator + (fra& t) { return fra(xx*t.yy+yy*t.xx,yy*t.yy); } fra fra::operator ++ () { return fra(xx,++yy); } fra fra::operator - (fra& t) { return fra(xx*t.yy-yy*t.xx,yy*t.yy); } fra fra::operator / (int n) { return fra(xx,yy*n); } fra& fra::operator = (fra& t) { xx=t.xx; yy=t.yy; return *this; } bool fra::operator == (fra& t) { if(xx==t.xx&&yy==t.yy) return true; return false; } bool fra::operator > (fra& t) { if(xx*t.yy>yy*t.xx) return true; return false; } bool fra::operator >= (fra& t) { if(xx*t.yy>=yy*t.xx) return true; return false; }
[ 本帖最后由 nicum 于 2011-9-20 13:13 编辑 ]