| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2542 人关注过本帖, 1 人收藏
标题:最优埃及分数,怎么搞
只看楼主 加入收藏
hwdwow
Rank: 2
等 级:论坛游民
帖 子:119
专家分:98
注 册:2009-3-21
收藏
得分:0 
//终极解决方案,参考了沙发的思路,感谢
#include <stdio.h>

#define N 10
int g_best[N],g_temp[N],g_nParts;
int g_found;

int Gcd(int m, int n)
{
    int t;
    while (m>0)
    {
        t=n%m;
        n=m;
        m=t;
    }
    return n;
}


void EgyptFraction(int m, int n, int k)
{
    int i,t,low,high;

    t=Gcd(m,n);
    m/=t;
    n/=t;

    if (k==1)
    {
        if (m==1)
        {
            g_temp[0]=n;
            if (!g_found || (g_found && n<g_best[0]))
            {
                g_found=1;
                for (i=0; i<g_nParts; i++)
                    g_best[i]=g_temp[i];
            }
        }
    }
    else
    {
        low=n/m+1;
        if (k<g_nParts && g_temp[k]+1>low)
            low=g_temp[k]+1;
        high = (k*n%m==0)? k*n/m-1:k*n/m;
        for (t=low; t<=high; t++)
        {
            g_temp[k-1]=t;
            EgyptFraction(m*t-n,n*t,k-1);
        }
    }
}


int main(void)
{
    int i,m,n;

    while (1)
    {
        printf("Please enter a proper fraction(a/b):");
        scanf("%d/%d",&m,&n);
        if (m==0)  
            break;
        if (m>=n || m<=0 || n<=0)
            continue;

        g_found=0;
        g_nParts=0;
        do
        {
            g_nParts++;
            EgyptFraction(m,n,g_nParts);
        }while (!g_found && g_nParts<N);

        if (g_found)
        {
            for (i=g_nParts-1; i>0; i--)
                printf("1/%d+",g_best[i]);
            printf("1/%d\n",g_best[0]);
        }
        else
            printf("Too complex!\n");


    }

    return 0;
}
2009-09-05 11:09
机器能
Rank: 2
等 级:论坛游民
帖 子:46
专家分:61
注 册:2009-8-24
收藏
得分:0 
回复 22楼 hwdwow
你写德泰好了,能给点中文注释吗?

不管黑猫白猫抓住老鼠就是好猫~
2009-09-05 12:48
机器能
Rank: 2
等 级:论坛游民
帖 子:46
专家分:61
注 册:2009-8-24
收藏
得分:0 
看了你的程序才知道自己的程序可读性太差了 ~你写得这么好我还看不懂~求求加点注释~

不管黑猫白猫抓住老鼠就是好猫~
2009-09-05 13:03
jimmywood
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:30
专家分:109
注 册:2009-8-10
收藏
得分:2 
怎么都喜欢直接贴程序呢...
能不能先简单说下算法思路...
2009-09-05 13:57
机器能
Rank: 2
等 级:论坛游民
帖 子:46
专家分:61
注 册:2009-8-24
收藏
得分:0 
回复 22楼 hwdwow
输入11/999计算结果错误~~~我的是216 296 333是正确的,你的有负数~~

不管黑猫白猫抓住老鼠就是好猫~
2009-09-05 14:34
zhaoguoge
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:46
专家分:121
注 册:2009-7-8
收藏
得分:0 
程序中出现double的肯定是错的,古埃及人还没有实数的概念呢
你懂不懂电脑的存储方式啊?你在电脑里给我用整型存个"19/45"这样的分数给我看看!!!!!!!!
我的算法绝对可行~~~~你不信可以自己拿机子跑跑   ~~~~动手才是硬道理!!!!!!
你光看就知道程序是错的  还要电脑干吗????????

程序代码:
#include <stdio.h>
int fun(int b);
void tran(int x, int y, int k);
void main()
{
    int a, b, n, k, i;
    
    printf("Input how many groups data\n");
    printf("And Input the  data  a  b (0<a<b<1000)\n");
    scanf("%d", &n);
    for(i = 0; i < n; i++)
    {
        scanf("%d%d", &a, &b);
        k = fun(b);
        tran(a,b,k);
        printf("\n");
    }
}
int fun(int b)
{
    int i, r;
    for(i = 1; i <= b; i++)
    {
        if((b%i == 0) && ((b/i - i) > 0))
        {
            r = i;
        }
    }
    return r;
}
void tran(int x, int y, int k)
{
    int a, b;
    double temp;
    
    a = x * k - y;
    b = y * k;
    temp = (double)a/b;
    if(temp > 0)
    {
        printf("%d  ", k);
        tran(a,b,k+1);
    }
    else if(temp < 0)
    {
        tran(x,y,k+1);
    }
    else if(temp == 0)
    {
        printf("%d", k);
    }
} 
  

 double temp;  是用来暂存A/B的植的   在实际生活中可以用分数形式   可是计算机是不行
     
    a = x * k - y;
    b = y * k;
这2个是把分数还原出来
2009-09-05 15:19
zhaoguoge
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:46
专家分:121
注 册:2009-7-8
收藏
得分:2 
沙发的算法本身有问题   他没考虑""最""这个因素
2009-09-05 15:21
UserYuH
Rank: 12Rank: 12Rank: 12
来 自:毅华
等 级:火箭侠
威 望:8
帖 子:720
专家分:3300
注 册:2009-8-10
收藏
得分:2 
我也写了个,看看结果,
思路:1~n的分之一逐个相加,把加等于a/b的组合存入数组中,然后输出最优。(这题较难,要说全思路不易,大至说这些)
输入:
a=19
b=45
输出:
19/45= 1/3 + 1/12+ 1/180
19/45= 1/3 + 1/12+ 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
·
zuiyou
19/45= 1/5 + 1/6 + 1/18
·
程序代码:
# define N 400

int tigui(long jia,long cheng)
{
 if(cheng%jia==0)
   return jia;
 else
   tigui(cheng%jia,jia);
}


void you(long *jia,long *cheng)
{
 long i;
 while(1)
   {
    i=tigui(*jia,*cheng);
    if(i==1)break;
    else
      {
       *jia/=i;
       *cheng/=i;
      }
   }
}



main()
  {
   int i,j,a,b,m=0,n=0,fm[20][5];
   unsigned long cheng,jia,k1,k2,k3,k4;
   printf("a=");
   scanf("%ld",&a);
   printf("b=");
   scanf("%ld",&b);
   for(k1=1;k1<10;k1++)
     {
      for(k2=((k1==1)?1:k1+1);k2<N;k2++)
    {
     for(k3=k2+1;k3<N;k3++)
       {
        for(k4=k3+1;k4<N;k4++)
          {
           if(k1==1&&k2==1)
         {
          cheng=k3*k4;
          jia=k3+k4;
          you(&jia,&cheng);
          if((float)jia/cheng<(float)a/b)
            break;
         }
           else if(k1==1)
              {
               cheng=k2*k3;
               jia=k2+k3;
               you(&jia,&cheng);
               if((float)jia/cheng>(float)a/b)
             break;

               jia=cheng+k4*jia;
               cheng=cheng*k4;
               you(&jia,&cheng);
               if((float)jia/cheng<(float)a/b)
             break;
              }
             else
               {
            cheng=k1*k2;
            jia=k1+k2;
            you(&jia,&cheng);
            if((float)jia/cheng>(float)a/b)
              {
               k3=N;
               break;
              }

            jia=cheng+jia*k3;
            cheng=cheng*k3;
            you(&jia,&cheng);
            if((float)jia/cheng>(float)a/b)
              break;

            jia=cheng+jia*k4;
            cheng=cheng*k4;
            you(&jia,&cheng);
            if((float)jia/cheng<(float)a/b)
              break;
               }

           if(jia==a&&cheng==b)
          {m=1;
           fm[n][0]=k1;
           fm[n][1]=k2;
           fm[n][2]=k3;
           fm[n][3]=k4;
           n++;
           break;
          }
          }
       }
     if(m==1&&k2==1)break;
    }
      if(m==1&&k1==1)break;
     }

   if(m==1)
     {


      for(i=0;i<n;i++)
    {
     printf("%d/%d= ",a,b);
     for(j=0;j<4;j++)
       {
        fm[i][4]=0;
        if(fm[i][j]!=1)
         {
          fm[i][4]+=fm[i][j];
          printf("1/%-2d",fm[i][j]);
          if(j<3)printf("+ ");
         }
       }
     printf("\n");
    }
      m=0;
      k1=fm[0][4];
      for(i=1;i<n;i++)
    {
     if(k1>=fm[i][4])
       {
        m=i;
        k1=fm[i][4];
       }
    }
      printf("\nzuiyou\n%d/%d= ",a,b);
      for(i=0;i<4;i++)
    if(fm[m][i]!=1)
     {
      printf("1/%-2d",fm[m][i]);
      if(i<3)printf("+ ");
     }
      printf("\n\n");
     }
   getch();
  }

努力—前进—变老—退休—入土
2009-09-06 14:32
ool
Rank: 2
等 级:论坛游民
帖 子:15
专家分:23
注 册:2009-8-5
收藏
得分:0 
以下是引用zhaoguoge在2009-9-5 15:21的发言:
沙发的算法本身有问题   他没考虑""最""这个因素
写这个算法的时候本就没考虑最优,我在前面自己已经说了!只是提供了一种分解方式而已
2009-09-06 16:18
zhaoguoge
Rank: 3Rank: 3
等 级:论坛游侠
帖 子:46
专家分:121
注 册:2009-7-8
收藏
得分:0 
这题是算法可以参考 物理学中并联电阻模型  
2009-09-06 23:58
快速回复:最优埃及分数,怎么搞
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.032918 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved