埃及分数稍微加了一点限制条件,我是拿它作为埃及分数,IDA*算法的连习题来做的,结果也改了很长时间,是因为忘记了改成long long了
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 100;
int maxd;
set<int> ban;
ll v[maxn],ans[maxn];
ll gcd(ll a,ll b)
{
if(!b) return a;
return gcd(b,a%b);
}
ll getfirst(ll a,ll b)
{
return b / a + 1;
}
bool better(int d)
{
for(int i = d;i >= 0;i--)
{
if(v[i] != ans[i])
return ans[i] == -1 || v[i] < ans[i];
}
return false;
}
bool dfs(int d,ll c,ll a,ll b)
{
if(d == maxd)
{
if(b % a) return false;
v[d] = b / a;
if(ban.count(v[d])) return false;
if(better(d)) memcpy(ans,v,sizeof(ll) * (d + 1));
return true;
}
bool ok = false;
c = max(c,getfirst(a,b));
for(int p = c;;p++)
{
if(ban.count(p)) continue;
if(b * (maxd + 1- d) <= a * p) break;
v[d] = p;
ll a1 = a * p - b;
ll b1 = b * p;
ll g = gcd(a1,b1);
if(dfs(d + 1,p + 1,a1/g,b1/g)) ok = true;
}
return ok;
}
int main()
{
int N; scanf("%d",&N);
for(int kase = 1;kase <= N;kase++)
{
int a,b,k;
ban.clear();
scanf("%d%d%d",&a,&b,&k);
for(int i = 1;i <= k;i++)
{
int x;
scanf("%d",&x);
ban.insert(x);
}
for(maxd = 1;;maxd++)
{
memset(v,-1,sizeof(v));
memset(ans,-1,sizeof(ans));
if(dfs(0,getfirst(a,b),a,b))
{
break;
}
}
printf("Case %d: %d/%d=",kase,a,b);
for(int i = 0;i <= maxd;i++)
{
if(i) printf("+");
printf("1/%lld",ans[i]);
}
printf("\n");
}
return 0;
}