• uva12558 Egyptian Fractions (HARD version)(迭代深搜)


    Egyptian Fractions (HARD version)

    题解:迭代深搜模板题,因为最小个数,以此为乐观估价函数来迭代深搜,就可以了。

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<algorithm>
     6 #include<cstdlib>
     7 #define LL long long
     8 #define N 10
     9 using namespace std;
    10 
    11 LL dep,flag,pre[N],now[N];
    12 bool book[1010];
    13 
    14 // 函数功能:求最大公约数
    15 LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
    16 
    17 // 函数功能:遍历第dep步的所有解
    18 void dfs(LL a,LL b,LL k)
    19 {
    20     if(b%a==0&&b/a>now[k-1]&&(b/a>1000||!book[b/a])) // 找到符合要求的结果
    21     {           /* 不要忘记判断最后的结果是否能使用,不然会WA,且要记得b/a的范围在1000以内才能判断,不然会数组越界 */
    22         /* 不能把book放下面判断,没有循环continue不能用,return会出错,可能没有到达dep步b%a==0,但是b/a是不能使用的 */
    23         now[k]=b/a;
    24         bool ans=0;
    25         for(int i=k;i>=1;i--)
    26         {
    27             if(now[i]<pre[i])
    28             {
    29                 ans=1;
    30                 break;
    31             }
    32             else if(now[i]>pre[i])
    33                 break;
    34         }
    35         if(!flag||ans)
    36             memcpy(pre,now,sizeof(now));
    37         flag=1;
    38         return ;
    39     }
    40     LL s=b/a;
    41     if(s<=now[k-1]) s=now[k-1]+1;
    42     LL t=(dep-k+1)*b/a;   // 迭代搜索执行到第dep步就结束了,限制上界
    43                           /* 之所以是这个公式是,s是使等式成立最接近的解,把s平均拆分成dep-k+1份,如果没t还小,剩下的dep-k步无论取多少都会偏小  */
    44     if(flag&&t>pre[dep]) t=pre[dep]-1;
    45     for(LL i=s;i<=t;i++)
    46     {
    47         if(i<=1000&&book[i]) // 判断这个点能否使用,不要忘记范围,不要越界访问
    48             continue;
    49         now[k]=i;
    50         LL m=gcd(a*i-b,b*i);
    51         dfs((a*i-b)/m,(b*i)/m,k+1);
    52     }
    53     return;
    54 }
    55 
    56 // 函数作用:简洁。可去掉,放在main函数中
    57 inline void slove(LL a,LL b)
    58 {
    59     now[0]=1;
    60     for(dep=2;dep<=N;dep++)
    61     {
    62         dfs(a,b,1);
    63         if(flag)
    64         {
    65             printf("1/%lld",pre[1]);
    66             for(LL i=2;i<=dep;i++)
    67                 printf("+1/%lld",pre[i]);
    68             printf("
    ");
    69             return;
    70         }
    71     }
    72 }
    73 
    74 int main()
    75 {
    76     int T,cnt=1;
    77     scanf("%d",&T);
    78     while(T--)
    79     {
    80         flag=0;memset(book,false,sizeof(book));
    81         LL a,b,k,x;
    82         scanf("%lld %lld %lld",&a,&b,&k);
    83         while(k--)
    84         {
    85             scanf("%lld",&x);
    86             book[x]=true;
    87         }
    88         printf("Case %d: %lld/%lld=",cnt++,a,b);
    89         slove(a,b);
    90     }
    91 }
  • 相关阅读:
    Objective-C 学习记录--toches、Motion/Size/Rect/Point/CGFloat/protocol
    Objective-C 学习记录6--dictionary
    Objc基础学习记录5
    第四篇:web之前端之jquery
    第三篇:web之前端之JavaScript基础
    第二篇:web之前端之css
    第一篇:web之前端之html
    第三篇:杂项之年终总结
    第二篇:杂项之图像处理pillow
    第一篇:杂项之pymysql连接池
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/7700802.html
Copyright © 2020-2023  润新知