题目链接:
https://vjudge.net/problem/UVA-12558
题意:
题解:
输出要用lld
IDA*迭代加深搜索
紫书例题改一改
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 #define MS(a) memset(a,0,sizeof(a)) 5 #define MP make_pair 6 #define PB push_back 7 const int INF = 0x3f3f3f3f; 8 const ll INFLL = 0x3f3f3f3f3f3f3f3fLL; 9 inline ll read(){ 10 ll x=0,f=1;char ch=getchar(); 11 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 13 return x*f; 14 } 15 ////////////////////////////////////////////////////////////////////////// 16 const int maxn = 10010; 17 18 ll a,b,k,maxd; 19 set<ll> ban; 20 ll ans[maxn],v[maxn]; 21 22 ll gcd(ll x,ll y){ 23 return y==0 ? x : gcd(y,x%y); 24 } 25 26 ll get_first(ll x,ll y){ 27 if(y%x == 0) return y/x; 28 return y/x+1; 29 } 30 31 bool better(int d){ 32 for(int i=d; i>=0; i--){ 33 if(v[i] != ans[i]) 34 return ans[i]==-1 || v[i]<ans[i]; 35 } 36 return false; 37 } 38 39 bool dfs(int d,ll from,ll aa, ll bb){ 40 if(d == maxd){ 41 if(bb%aa) return false; 42 if(ban.count(bb/aa)) return false; 43 v[d] = bb/aa; 44 if(better(d)) memcpy(ans,v,sizeof(ll)*(d+1)); 45 return true; 46 } 47 48 bool ok = false; 49 from = max(from,get_first(aa,bb)); // 因为aa/bb 越来越小, bb/aa 越来越大,所以每次枚举的起点是递增的,不会重复 50 for(ll i=from; ; i++){ 51 if((maxd-d+1)*bb <= i*aa) break; 52 if(ban.count(i)) continue; 53 v[d] = i; 54 ll b2 = bb*i; 55 ll a2 = aa*i-bb; 56 ll g = gcd(a2,b2); 57 if(dfs(d+1,i+1,a2/g,b2/g)) ok = true; // 这里为什么不直接返回true了? 这一层要继续,会影响后面的值,当前层大了,后面就要有更小的分数出现,不是最优解 58 // i+1保证了不重复性 59 } 60 return ok; 61 } 62 63 int main(){ 64 int T = read(); 65 for(int cas=1; cas<=T; cas++){ 66 ban.clear(); 67 scanf("%I64d%I64d%I64d",&a,&b,&k); 68 for(int i=0; i<k; i++){ 69 ll t = read(); 70 ban.insert(t); 71 } 72 73 // cout << get_first(a,b) << endl; 74 for(maxd=1; ; maxd++){ 75 memset(ans,-1,sizeof(ans)); 76 if(dfs(0,get_first(a,b),a,b)) break; 77 } 78 79 printf("Case %d: %lld/%lld=",cas,a,b); 80 for(int i=0; i<maxd; i++) 81 printf("1/%lld+",ans[i]); 82 printf("1/%lld ",ans[maxd]); 83 } 84 85 return 0; 86 }