正文

[TOJ]1029埃及分数2005-06-10 13:41:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/rickone/1618.html

分享到:

埃及分数 Time Limit:2s Memory Limit:1000k Total Submit:2302 Accepted:340 下载样例程序(PE) 下载样例程序(ELF) -------------------------------------------------------------------------------- Problem 在古埃及,人们使用单位分数的和(形如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都大。 给出a,b(0〈a〈b〈1000),编程计算最好的表达方式。 Input 第一行:N 表示有N组测试数据,每组测试数据为一行包含a,b(0〈a〈b〈1000)。 Output 每组测试数据若干个数,自小到大排列,依次是单位分数的分母。 Sample Input 1 19 45 Sample Output 5 6 18 Source oibh #include <iostream> #include <algorithm> #include <cstdlib> #include <cmath> #include <iomanip> using namespace std; const double zero=1e-20; const double maxn=1e20; int num; bool bb; double tempa[1000],tempb[1000],best[1000],v[1000]; int g_cd(int a,int b) {     int ta,tb;     ta=a;tb=b;     if(ta<tb)swap(ta,tb);     if(!(ta%tb))return tb;     else return g_cd(tb,ta%tb); } void solve(int x) {     int i,next,temp,prev;     if(x>num)     {         if(fabs(tempa[num])<zero)         {                 bb=1;                 if(v[num]<best[num])                  for(i=1;i<=num;i++)                     best[i]=v[i];         }     }else     {         prev=(int(tempb[x-1]/tempa[x-1])>int(v[x-1]+1))?int(tempb[x-1]/tempa[x-1]):int(v[x-1]+1);         next=int((num-x+1)*tempb[x-1]/tempa[x-1]+zero);         if(tempb[x-1]/tempa[x-1]+num-x+1>best[num])return;         for(i=prev;i<=next;i++)         {             v[x]=i;             tempa[x]=tempa[x-1]*i-tempb[x-1];             if(tempa[x]<0)continue;             tempb[x]=tempb[x-1]*i;             if(tempa[x]>-zero && int(tempa[x]*v[x]/tempb[x])<=num-x)               solve(x+1);         }     } } int main(int argc, char *argv[]) {     int i,j,n,temp,a,b;     cin>>n;     for(j=0;j<n;j++)     {         cin>>a>>b;         temp=g_cd(a,b);         a/=temp;b/=temp;         if(a==1)               cout<<b<<endl;         else         {                 v[0]=b/a;num=1;                 bb=0;best[1]=maxn;                 while(1)                 {                     num++;                     best[num]=maxn;                     tempa[0]=a;tempb[0]=b;                     solve(1);                     if(bb)break;                 }                 for(i=1;i<num;i++)                     cout<<setiosflags(ios::fixed)<<setprecision(0)<<best[i]<<' ';                 cout<<best[num]<<endl;         }     }     //system("PAUSE");         return 0; }

阅读(38150) | 评论(0)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

暂无评论
您需要登录后才能评论,请 登录 或者 注册