• LOJ P10022 埃及分数 题解


    每日一题 day62 打卡

    Analysis

    这道题一看感觉很像搜索,但是每次枚举x∈(1,10000000)作为分母显然太蠢了。

    所以我们要想办法优化代码。

    优化一:迭代加深

    优化二:

    我们确定了搜索方式,现在就要确定搜索的上下界。

    因为现在搜索的分数一定要比剩下的值小,于是有:

    1/i​<x/y

    上界满足 y<xi

    设还有k个分数,因为枚举的分母是单调递增的,所以分数的值是单调递减的,可得后k个分数的值严格小于k/i,而这个值一定要比当前剩下的值大,

    于是有:

    k/i>x/y
    下界满足 ky>xi

     

    优化想好了之后就可以安心码代码~~~

    注意:一些细节在代码中有注释

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #define int long long
     6 #define INF 2147483647
     7 #define maxn 100000+10
     8 #define rep(i,s,e) for(register int i=s;i<=e;++i)
     9 #define dwn(i,s,e) for(register int i=s;i>=e;--i)
    10 using namespace std;
    11 inline int read()
    12 {
    13     int x=0,f=1;
    14     char c=getchar();
    15     while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
    16     while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();}
    17     return f*x;
    18 }
    19 void write(int x)
    20 {
    21     if(x<0) {putchar('-'); x=-x;}
    22     if(x>9) write(x/10);
    23     putchar(x%10+'0');
    24 }
    25 int a,b;
    26 int t,len;
    27 int s[maxn],ans[maxn];
    28 inline int calc(int x,int y)
    29 {
    30     rep(i,2,INF)
    31         if(x*i>y)
    32             return i;
    33 }
    34 bool dfs(int rest,int x,int y)//因为要方便判断枚举的长度可不可以,所以选择bool类型的搜索 
    35 {
    36     if(rest==1)
    37     {
    38         if(x==1&&y>s[t]&&(len==0||y<ans[len]))
    39         {
    40             len=++t;
    41             s[t]=y;
    42             rep(i,1,t) ans[i]=s[i];
    43             --t;
    44             return true;
    45         }
    46         return false;
    47     }
    48     bool flag=false;
    49     for(register int i=max(s[t]+1,calc(x,y));rest*y>i*x;++i)
    50     {
    51         int now_x=x*i-y;
    52         int now_y=y*i;//nx/xy=x/y-1/i; 
    53         int mod=__gcd(now_x,now_y);
    54         now_x/=mod;
    55         now_y/=mod;
    56         s[++t]=i;
    57         if(dfs(rest-1,now_x,now_y)==true) flag=true; 
    58         --t;
    59     }
    60     return flag;
    61  } 
    62 signed main()
    63 {
    64     a=read();b=read();
    65     int mod=__gcd(a,b);
    66     a/=mod;
    67     b/=mod;
    68     if(a==1) {write(b); return 0;}
    69     s[0]=1;
    70     rep(i,2,INF)
    71     {
    72         t=0;
    73         if(dfs(i,a,b)==true)
    74         {
    75             rep(j,1,len) 
    76             {
    77                 write(ans[j]); 
    78                 putchar(' ');
    79             }
    80             break;//第一次搜到的答案一定是最优 
    81         }    
    82     }
    83     return 0;
    84 }

    如有失误请各位大佬斧正(反正我不认识斧正是什么意思)

  • 相关阅读:
    JavaScript 复制变量的三种方法
    WIndows cmd command 指令总结
    Linux 指令总结
    如何在当前目录下打开Windows cmd?
    git使用笔记(四)错误报告 Git push rejected error: fatal: refusing to merge unrelated histories
    CentOS(Linux)
    CentOS(Linux)
    异常描述:hibernate懒加载中,用OpenSessionInViewFilter解决之后,同时对一个collection创建两个session访问导致异常(Illegal attempt to associate a collection with two open sessions)
    【转】hibernate懒加载的问题,failed to lazily initialize a collection of role
    JavaWeb项目里面的路径获取方法总结
  • 原文地址:https://www.cnblogs.com/handsome-zyc/p/12076449.html
Copyright © 2020-2023  润新知