zoukankan      html  css  js  c++  java
  • hdu--4574 Bombs(dfs)

    Terrorists are around everywhere, they always make troubles by detonating bombs. The terrorist have some gunpowder to make bombs, different gunpowder has different damage, every kind of gunpowder can use any times, and the power of one bomb is the product of the gunpowder it consists of. Let’s see how they make a bomb. 
      At the beginning they decide to use X parts of gunpowder to make a bomb, and then choose X parts of gunpowder, every time the damage of the gunpowder they choose can’t be smaller than the last time they choose excepting the first time. After choosing X parts gunpowder terrorists get gunpowder11, gunpowder22 ... gunpowderXX ( gunpowder11 <= gunpowder22 <= ... <= gunpowderXX), and then mix the X parts gunpowder to generate a bomb with power of the product of the damage of the gunpowder. Terrorists make bombs in some order, if they make bomb_A before bomb_B one of the following conditions should meet. 
    (1)Terrorists use less parts gunpowder to make bomb_A than bomb_B. 
    (2)Terrorists both use X parts of gunpowders to make bomb_A and bomb_B. There exist an integer j(j <=X),for all i < j,gunpowder_Aii = gunpowder_Bii and gunpowder_Ajj < gunpowder_Bjj. 
      Now, the police get the gunpowder by some way, police find that the gunpowder’s damage is in the range of A to B(A, B included), police want to know the K-th bomb with the power in the range of L to R(L, R included).
    Input  There are multiple cases, the first line is an integer T denoting the number of the case, for each case has five integers A, B, L, R, K in a line. A, B denote the damage range of the gunpowder. L, R denote the power range of the bomb, K denotes the K-th bomb with the power in the range L to R that police want to know. 
    2<=A <= B<=10^6 
    1<=L<=R<=10^9 
    1<=K<=10^6Output  For each case output in the format in the first line “Case #x: y” x is the case number start from 1, y is the power of the bomb, and the second line with the gunpowder in the order they choose. If there is no more than K bombs in the range of L to R just output one line “Case #x: -1”.Sample Input
    4
    2 2 1 4 1
    2 5 1 4 4
    73 23642 12 20903 29401
    2 50 1 1000000000 815180
    Sample Output
    Case #1: 2
    2
    Case #2: 4
    2 2
    Case #3: -1
    Case #4: 59200
    4 4 5 20 37
    
            
     
    Hint
    In the second case we have 4 kinds of gunpowder with damage 2, 3, 4, 5.
    the first bomb is “2”with power of 2 
    The second bomb is “3” with power of 3
    The third bomb is “4” with power of 4
    The fouth bomb is “5” with power of 5
    The fifth bomb is “2 2” with power of 2 * 2 = 4
    So the 4-th bomb with power in the range of 1 to 4 is “2 2”.
    

     题意:有A—B各种不同大小的原料,能够制成各种炸弹,炸弹的威力是原料的乘积。炸弹威力的范围都在[L,R]之间,问第K枚炸弹是由哪些原料组成的。炸弹是按照原料的字典序排列的。

    思路:根据数据范围可知道最多有30层,然后求出每一层可制造多少个炸弹,进而求出制造出第k枚炸弹需要多少层。然后在该层依次找出制造第k枚炸弹所用的具体的原料

    AC代码:

      1 //函数dfs()找到第 i 层数组合在[l,r]范围内有多少个数
      2 /*剪枝的意义:判断前 i-1 层数+第 i 层数的第 j 部分比 k 多就直接跳出了,
      3 因为可以推出第 k 个可用数一定是由前 i 层数的乘积组成的*/
      4 /*函数count_ans()目的是往前推找出第 k 个可用数的每一个数,
      5 if(k>cnt) 说明该层第 i 个数被完全排满了,否则说明没有被排满*/
      6 //注意事项:题目中不能够全部都用long long 
      7 #include <iostream>
      8 #include <cstdio>
      9 #include <cstring>
     10 #include <queue>
     11 #include <algorithm>
     12 #include <map>
     13 #include <set>
     14 #include <stdlib.h>
     15 #include <stack>
     16 #include <vector>
     17 #include <cmath>
     18 #define ll long long
     19 using namespace std;
     20 const int inf=1000000000;
     21 int count_pow(int a,int b)
     22 {
     23     int ans=a;
     24     for(int i=1;i<b;i++)
     25     {
     26         ans=ans*a;
     27         if(ans>inf||ans<=0)
     28             return inf+1;
     29     }
     30     return ans;
     31 }
     32 int dfs(int c,int a,int b,int l,int r,int k)
     33 {
     34     if(c==0) return l<=r;
     35     if(c==1)
     36     {
     37         if(r<l) return 0;
     38         else return max(0,(min(b,r)-max(a,l)+1));
     39     }
     40     int down=max(a,l/count_pow(b,c-1));//所需的最小原料
     41     int up=min(b,r/count_pow(a,c-1));//所需的最大原料
     42     int cnt=0;
     43     for(int i=down;i<=up;i++)
     44     {
     45         cnt+=dfs(c-1,i,b,(l+i-1)/i,r/i,k-cnt);
     46         if(cnt>k)
     47             return cnt;//剪枝
     48     }
     49     return cnt;
     50 }
     51 int ret,ans[50];
     52 void count_ans(int c,int a,int b,int l,int r,int k)
     53 {
     54     if(c==1)
     55     {
     56         int num=max(l,a)+k-1;
     57         ret=ret*num;
     58         ans[c]=num;
     59         return ;
     60     }
     61     int down=max(a,l/count_pow(b,c-1));
     62     int up=min(b,r/count_pow(a,c-1));
     63     for(int i=down;i<=up;i++)
     64     {
     65         int cnt=dfs(c-1,i,b,(l+i-1)/i,r/i,k);
     66         if(k>cnt)// i 这种原料是否能够被完全使用
     67         {
     68             k=k-cnt;
     69             continue;
     70         }
     71         ret=ret*i;
     72         ans[c]=i;
     73         count_ans(c-1,i,b,(l+i-1)/i,r/i,k);//求下一种原料
     74         return ;
     75     }
     76 }
     77 int main()
     78 {
     79     int t;
     80     int a,b,l,r,k;
     81     scanf("%d",&t);
     82     {
     83         for(int v=1;v<=t;v++)
     84         {
     85             scanf("%d%d%d%d%d",&a,&b,&l,&r,&k);
     86             printf("Case #%d: ",v);
     87             int flag=0;
     88             for(int i=1;i<=30;i++)
     89             {
     90                 int cnt=dfs(i,a,b,l,r,k);
     91                 
     92                 if(k>cnt)
     93                 {
     94                     k=k-cnt;
     95                     continue;
     96                 }
     97                 ret=1;
     98                 count_ans(i,a,b,l,r,k);
     99                 printf("%d
    ",ret);
    100                 for(int j=i;j>=1;j--)
    101                 {
    102                     printf("%d%c",ans[j],j==1?'
    ':' ');
    103                 }
    104                 flag=1;
    105                 break;
    106             }
    107             if(!flag)
    108                 printf("-1
    ");
    109         }
    110     }
    111     return 0;
    112 }
    View Code
  • 相关阅读:
    jQuery插件之jqzoom
    python数据分析画图体验
    python正则表达式,以及应用[下载图片]
    Python 程序如何高效地调试?
    从汉诺塔游戏理解python递归函数
    Python文本文件的输入输出操作学习
    Windows搭建python开发环境
    python循环综合运用
    Python参数传递,既不是传值也不是传引用
    使用python实现用微信远程控制电脑
  • 原文地址:https://www.cnblogs.com/wang-ya-wei/p/6920970.html
Copyright © 2011-2022 走看看