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 gunpowder 1 1, gunpowder 2 2 ... gunpowder X X ( gunpowder 1 1 <= gunpowder 2 2 <= ... <= gunpowder X X), 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_A i i = gunpowder_B i i and gunpowder_A j j < gunpowder_B j j.
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).
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 gunpowder 1 1, gunpowder 2 2 ... gunpowder X X ( gunpowder 1 1 <= gunpowder 2 2 <= ... <= gunpowder X X), 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_A i i = gunpowder_B i i and gunpowder_A j j < gunpowder_B j j.
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).
2<=A <= B<=10^6
1<=L<=R<=10^9
1<=K<=10^6
4 2 2 1 4 1 2 5 1 4 4 73 23642 12 20903 29401 2 50 1 1000000000 815180
Case #1: 2
2
Case #2: 4
2 2
Case #3: -1
Case #4: 59200
4 4 5 20 37
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”.
给出火药的范围和炸弹威力的范围,多种火药造出的炸弹的威力是这些数的乘积。根据所给的火药范围可以有多种配方情况,问按字典序排,第k中配方(威力必须在所给范围内)的造出炸弹的威力以及列举出第k中配方用到的所有火药,结果按升序输出,如果不存在输出-1.
排序时先按长度排,再按字典序排例如给出火药范围1~3
所有的配方就是
1
2
3
1 2
1 3
2 3
1 2 3
题中所给炸弹的最大威力为1e9,而火药的最小值为2,所以一种炸弹最多有30种火药配成,首先我们先枚举火药的种数,然后再bfs求出每一层能配成的炸弹的数量,当我们枚举到一层算出加到该层的数量>=k时,我们可以确定第k个数一定在这一层,然后我们再一次bfs一次求出第k个数的组成即可
也是看了网上的代码才回的,确定上下限的剪枝非常nice
ac代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <map>
#include <set>
#include <stdlib.h>
#include <stack>
#include <vector>
#include <cmath>
#define ll long long
using namespace std;
const int inf=1000000000;
int count_pow(int a,int b)
{
int ans=a;
for(int i=1;i<b;i++)
{
ans=ans*a;
if(ans>inf||ans<=0)
return inf+1;
}
return ans;
}
int dfs(int c,int a,int b,int l,int r,int k)
{
if(c==1)
{
if(r<l) return 0;
else return max(0,(min(b,r)-max(a,l)+1));
}
int down=max(a,l/count_pow(b,c-1));
int up=min(b,r/count_pow(a,c-1));
int cnt=0;
for(int i=down;i<=up;i++)
{
cnt+=dfs(c-1,i,b,(l+i-1)/i,r/i,k-cnt);
if(cnt>k)
return cnt;
}
return cnt;
}
int ret,ans[50];
void count_ans(int c,int a,int b,int l,int r,int k)
{
if(c==1)
{
int num=max(l,a)+k-1;
ret=ret*num;
ans[c]=num;
return ;
}
int down=max(a,l/count_pow(b,c-1));
int up=min(b,r/count_pow(a,c-1));
for(int i=down;i<=up;i++)
{
int cnt=dfs(c-1,i,b,(l+i-1)/i,r/i,k);
if(k>cnt)
{
k=k-cnt;
continue;
}
ret=ret*i;
ans[c]=i;
count_ans(c-1,i,b,(l+i-1)/i,r/i,k);
return ;
}
}
int main()
{
int t;
int a,b,l,r,k;
scanf("%d",&t);
{
for(int v=1;v<=t;v++)
{
scanf("%d%d%d%d%d",&a,&b,&l,&r,&k);
printf("Case #%d: ",v);
int flag=0;
for(int i=1;i<=30;i++)
{
int cnt=dfs(i,a,b,l,r,k);
if(k>cnt)
{
k=k-cnt;
continue;
}
ret=1;
count_ans(i,a,b,l,r,k);
printf("%d\n",ret);
for(int j=i;j>=1;j--)
{
printf("%d%c",ans[j],j==1?'\n':' ');
}
flag=1;
break;
}
if(!flag)
printf("-1\n");
}
}
return 0;
}