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.
  • 相关阅读:
    (一)maven基本配置,概念,常用命令
    redis 小结
    git 小结
    spring.xml
    servlet web.xml学习笔记
    springmvc小试牛刀
    maven
    springmvc学习笔记1
    springmvcpojo
    springmvc学习笔记
  • 原文地址:https://www.cnblogs.com/Xiper/p/4467774.html
Copyright © 2011-2022 走看看