• 紫书搜索 习题7-7 UVA


    题目链接:

    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 }
  • 相关阅读:
    AngularJS学习之旅
    webbug3.0菜鸟笔记1
    CTF练习(1)这是一张单纯的图片?
    三步删除U深度,老毛桃,大白菜捆绑软件!!
    flex弹性布局学习总结
    C# 播放音乐
    获取文件夹中的所有文件名
    C# 利用委托和事件 传入一个参数进行进行计算并返回结果
    C# 自定义颜色
    检测键盘是否按下指定按键
  • 原文地址:https://www.cnblogs.com/yxg123123/p/6827598.html
Copyright © 2020-2023  润新知