您的位置:首页 > 其它

UVA 埃及分数问题

2016-01-24 23:32 316 查看
题目大意:给定一个分数a/b,他可以被表示成多个单位分数(1/a)之和的形式,如2/3=1/2+1/3,而且可能不止一种,如5/12=1/3+1/12=1/4+1/6.要求你写出给定分数a/b的单位分数之和的形式,若不止一种,则选择项数最少的,若项数相等,则选择最小元素最大的,若最小元素相等则选择第二小元素最大的,。。。。

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<set>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
typedef long long LL;
LL a,b;
int ans[5000];
int maxd=1;
int best[5000];
LL get_first(LL a,LL b){//找到并返回使(1/c)小于(a/b)的最小c
LL c;
if (b%a==0) c=b/a;
else c=(b/a)+1;
return c;
}

bool isbetter(){

for (int i = maxd; i >= 1; i--)//由于分母是由小到大存储的,因此逆序枚举
if (ans[i] != best[i])
return best[i] == -1 || ans[i]<best[i];
return false;

}

LL gcd(LL a, LL b)
{
return b == 0 ? a : gcd(b, a%b);
}

bool dfs(int d,LL c,LL a,LL b){//还剩a/b,接下来取的分数
bool ok=false;
if (d==maxd-1){//只能再加一个了
if(b%a==0) {
ans[maxd]=b/a;
if (isbetter()){
memcpy(best+1,ans+1,maxd*sizeof(int));
return true;
}

}
return false;
}
LL from=c>get_first(a,b)?c:get_first(a,b);//取两者之大着
for (int i=from;;i++){
//乐观的估计i及之后的可不可以取
if((maxd-d)*b<a*i) {
break;
}
ans[d+1]=i;
LL bb=b*i;
LL aa=a*i-b;
int g=gcd(aa,bb);
if(dfs(d+1,c+1,aa/g,bb/g)) ok=true;

}

return ok;
}

int main(){
int num=1;
while(scanf("%ld %ld",&a,&b)){
maxd=1;
memset(best,-1,sizeof(int)*5000);
while (!dfs(0,get_first(a,b),a,b))	{
maxd++;
}
printf ("Case %d:%d/%d=",num,a,b);
for (int i=1;i<=maxd;i++){
printf ("1/%d",best[i]);
if (i<maxd) printf ("+");
}
printf("\n");
num++;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: