原题链接:https://vjudge.net/problem/UVA-12558
分类:迭代剪枝
备注:IDA*,注意细节
有两个注意点,一是开long long,二是别把0x3f3f3f3f作为inf,应该换成-1,估计是正好有分母等于这个数。
剪枝就注意一下分母开始的数即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e6;
typedef long long ll;
int a,b,k,t,kase,flg;
ll ans[maxn],tmp[maxn];
map<ll,bool>ban;
ll gcd(ll a,ll b){
return b==0?a:gcd(b,a%b);
}
void idastar(ll st,ll a,ll b,int now,int maxd){
if(now==maxd){
if(a==0){
flg=1;
int pos=now-1;
while(pos>0&&ans[pos]==tmp[pos])pos--;
if(ans[0]==-1||(pos>0&&ans[pos]>tmp[pos]))
for(int i=0;i<now;i++)ans[i]=tmp[i];
}
return;
}
st=max(st,(b%a==0?b/a:b/a+1));
ll lim=(maxd-now)*b,t=st*a;
for(ll x=st;t<=lim;x++,t+=a){
if(x*a<b||ban.count(x))continue;
ll g=gcd(x*a-b,x*b); tmp[now]=x;
idastar(x+1,(x*a-b)/g,x*b/g,now+1,maxd);
}
}
int main(void){
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
scanf("%d",&t);
while(t--){
scanf("%d %d %d",&a,&b,&k);
ban.clear();
for(int i=0;i<k;i++){
ll x; scanf("%lld",&x);
ban[x]=true;
}
int d=2;
memset(ans,-1,sizeof(ans));
flg=0;
while(!flg){idastar(2,a,b,0,d); d++;}
d--;
printf("Case %d: %d/%d=",++kase,a,b);
for(int i=0;i<d;i++)printf("1/%lld%c",ans[i],i==d-1?'\n':'+');
}
return 0;
}