zoukankan      html  css  js  c++  java
  • UVA_埃及分数(Hard Version) UVA 12588

    Problem E
    Eg[y]ptian Fractions (HARD version)
    Given a fraction a/b, write it as a sum of different Egyptian fraction. For
    example, 2/3=1/2+1/6.
    There is one restriction though: there are k restricted integers that should not
    be used as a denominator. For example, if we can't use 2~6, the best solution is:
    2/3=1/7+1/8+1/9+1/12+1/14+1/18+1/24+1/28
    The number of terms should be minimized, and then the large denominator should be
    minimized. If there are several solutions, the second largest denominator should
    be minimized etc.
    Input
    The first line contains the number of test cases T(T<=100). Each test case begins
    with three integers a, b, k(2<=a<b<=876, 0<=k<=5, gcd(a,b)=1). The next line
    contains k different positive integers not greater than 1000.
    Output
    For each test case, print the optimal solution, formatted as below.
    Sample Input
    5 2
    3 0
    19 45 0
    2 3 1 2
    5 121 0
    5 121 1 33
    Output for the Sample Input
    Case 1: 2/3=1/2+1/6
    Case 2: 19/45=1/5+1/6+1/18
    Case 3: 2/3=1/3+1/4+1/12
    Case 4: 5/121=1/33+1/121+1/363
    Case 5: 5/121=1/45+1/55+1/1089
    Extremely Important Notes
    It's not difficult to see some inputs are harder than others. For example, these
    inputs are very hard input for every program I have:
    596/829=1/2+1/5+1/54+1/4145+1/7461+1/22383
    265/743=1/3+1/44+1/2972+1/4458+1/24519
    181/797=1/7+1/12+1/2391+1/3188+1/5579
    616/863=1/2+1/5+1/80+1/863+1/13808+1/17260
    22/811=1/60+1/100+1/2433+1/20275
    732/733=1/2+1/3+1/7+1/45+1/7330+1/20524+1/26388
    However, I don't want to give up this problem due to those hard inputs, so I'd
    like to restrict the input to "easier" inputs only. I know that it's not a perfect
    problem, but it's true that you can still have fun and learn something, isn't it?
    Some tips:
    Watch out for floating-point errors if you use double to store intermediate
    result. We didn't use double.
    Watch out for arithmetic overflows if you use integers to store intermediate
    result. We carefully checked our programs for that.

    解题报告

    迭代加深搜索。。注意带入上一个的分母,并且保证升序就可以辣,注意不要使用受限制的分母

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <algorithm>
      5 typedef long long LL;
      6 using namespace std;
      7 LL ban[5];
      8 int ban_num;
      9 int maxd;
     10 LL ans[1000];
     11 LL temp[1000]; 
     12 
     13 LL gcd(LL a,LL b)
     14 {
     15  return b == 0 ? a : gcd(b,a%b);    
     16 }
     17 
     18 
     19 
     20 
     21 
     22 /* gs 保证升序            */
     23 bool dfs(LL a,LL b,LL gs,int d)
     24 {
     25  if (d == maxd)
     26   {
     27       if (b % a || b <= temp[d-1]) return false;
     28       /*Check Last Num                     */
     29       for(int i = 0 ;i<ban_num;++i)
     30        if (b == ban[i])
     31         return false;
     32       temp[d] = b;
     33       int ok = 0;
     34       for(int i = d;i>=0;--i)
     35        if(ans[i] == -1)
     36         {
     37             ok = 1;
     38             break;
     39         }        
     40      else if(ans[i] != temp[i])
     41       {
     42           if (temp[i] < ans[i])
     43            ok = 1;
     44            break;
     45       }
     46     if (ok)
     47      memcpy(ans,temp,sizeof(LL) * (d+1));
     48     return true;
     49   }
     50  bool c = false;
     51  LL start = max(b/a + 1,gs);
     52  for(int i = start;;++i)
     53   {
     54       int ok = 1;
     55       if ( a * i > b*(maxd - d + 1)) break;
     56       for(int j = 0;j<ban_num;++j)
     57           if (i == ban[j])
     58           {
     59               ok = 0;
     60               break;
     61           }
     62        if (!ok) continue;
     63       LL na = a*i - b;
     64       LL nb = b*i;
     65       LL gc_ = gcd(na,nb);
     66       temp[d] = i;
     67       if (dfs(na/gc_,nb/gc_,i+1,d+1))
     68        c= true;
     69   }
     70  return c;    
     71 }
     72 
     73 
     74 
     75 
     76 
     77 int main(int argc,char * argv[])
     78 {
     79  int T2 = 1;
     80  int T;
     81  cin >> T;
     82  while(T--)
     83  {
     84      memset(ans,-1,sizeof(ans));
     85      LL a,b;
     86      cin >> a >> b >> ban_num;
     87      for(int i = 0 ; i < ban_num;++i)
     88       cin >> ban[i];      
     89     for(int i = 1;;++i)
     90      {
     91          maxd = i;
     92          if (dfs(a,b,0,0))
     93           break;
     94      }
     95     printf("Case %d: %lld/%lld=",T2++,a,b);
     96     for(int i = 0;i<=maxd;++i)
     97      i == 0 ? printf("1/%lld",ans[i]) : printf("+1/%lld",ans[i]);
     98     printf("
    ");
     99     
    100  }    
    101  return 0;
    102 }
    No Pain , No Gain.
  • 相关阅读:
    表单元素的required,autocomplete,list用法
    通用triggerEvent方法
    通用addEventListener方法
    关于动态加载js
    Node路由简单的处理
    As3截图转换为ByteArray传送给后台node的一种方法
    JS中的“==”符号及布尔值转换规则
    解释JS变量作用域的范例
    .NET异步委托
    正则表达式入门
  • 原文地址:https://www.cnblogs.com/Xiper/p/4467774.html
Copyright © 2011-2022 走看看