剪枝很重要,,还要注重最小分数要依次最大,好。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctype.h>
#include<vector>
#include<algorithm>
using namespace std;
#define N 100
long long a,b;
long long pre[1000];
int num=0;
long long ans[1000];
bool f;
long long gcd(long long big,long long small)
{
if (big<small)
swap(big,small);
if (big%small==0)
return small;
return gcd(small,big%small);
}
void put(int k)
{
int i;
for (i=1;i<k;i++)
{
cout<<"1/"<<pre[i]<<'+';
}
cout<<"1/"<<pre[k]<<endl;
}
void get(long long x,long long y,int step,int cur)
{
//cout<<x<<' '<<y<<' '<<step<<' '<<cur<<endl;
long long i,j;
if (cur==step)
{
if (x==1)
{
//cout<<"yes"<<endl;
pre[step]=y;
//put(step);
if (!f)
{
for (i=1;i<=step;i++)
ans[i]=pre[i];
}
else
{
int temp;
bool flag=false;
for (temp=step;temp>0;temp--)
{
if (pre[temp]<ans[temp])
break;
}
for (temp++;temp<=step;temp++)
{
if (pre[temp]>ans[temp])
break;
}
if (temp>step)
{
for (i=1;i<=step;i++)
ans[i]=pre[i];
}
}
f=true;
}
return ;
}
j=y/x;
j=max(pre[cur-1]+1,j);
j=max(j,(long long )2);
while (x*j-y<=0)
j++;
while(true)
{
long long z=x*j-y;
long long m=y*j;
i=gcd(z,m);
z/=i;
m/=i;
if (step-cur<(z*j)/m)
return ;
if (z*j>=(step-cur)*m)
return ;
pre[cur]=j;
get(z,m,step,cur+1);
j++;
}
}
int main()
{
int i,j;
long long k;
int t;
cin>>t;
while (t--)
{
cin>>a>>b;
if (a<=0||b<=0)
break;
k=gcd(a,b);
a/=k;
b/=k;
pre[0]=1;
f=false;
for (i=1;i<=N;i++)
{
(get(a,b,i,1));
if (f)
{
break;
}
}
for (j=1;j<=i;j++)
{
cout<<ans[j]<<' ';
}
cout<<endl;
}
return 0;
}
分数拆分
Time Limit: 2000 ms Memory Limit: 65535 kB Solved: 43 Tried: 694
Description
任何一个分数都能才成若干个单位分数(形如1/a的, a是自然数)的和。
对于一个分数a/b,表示方法有很多种,但是哪种最好呢?
首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越好,如果还是相同,那么第二小的分数越大越好,依次类推下去。
例如对于19/45,下列方法都是合法的:
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
第一行有一个整数T,表示有T(T<=50)组测试数据,每组测试数据为一行包含a,b(0<a<b<1000)。
Output
每组测试数据若干个数,自小到大排列,依次是单位分数的分母。
Sample Input
1
19 45
Sample Output
5 6 18