G - 土耳其冰淇凌 Gym - 101194D
题目
熊猫先生非常喜欢冰淇淋,尤其是冰淇淋塔。一个冰淇淋塔由K个冰淇淋球堆叠成一个塔。为了使塔稳定,下面的冰淇淋球至少要有它上面的两倍大。换句话说,如果冰淇淋球从上到下的尺寸是A0, A1, A2,···,AK 1,那么A0×2 ≤ A1, A1 × 2 ≤ A2,等等。
有一天,熊猫先生在街上走着,发现一家卖冰淇淋球的商店。冰淇淋球共有N个,大小分别为B0、B1、B2、··、BN−1。潘达先生想知道这些球最多能做出的冰淇淋塔数量。
输入
输入的第一行给出了测试用例的数量,接下来是T , T组测试用例。每个测试用例都以一个由2个整数组成的行开始,N是商店中冰淇淋球的数量,K是形成一个冰淇淋塔所需的冰淇淋球的数量。下一行包含N个整数,表示商店中各个冰淇淋球的大小
输出
对于每个测试用例,输出一行包含“Case #x: y”,其中x是测试用例号(从1开始),y是冰淇淋塔的最大数量。
• 1 ≤ T ≤ 100.
• 1 ≤ N ≤ 3 × 105.
• 1 ≤ K ≤ 64.
• 1 ≤ Bi ≤ 1018.
Sample Input
3
4 2
1 2 3 4
6 3
1 1 2 2 4 4
6 3
1 1 2 2 3 4
Sample Output
Case #1: 2
Case #2: 2
Case #3: 1
题意:
给你一些n个冰淇淋球,每k个冰淇淋球堆起来成为一个冰淇淋,但是对于每个冰淇淋,要保证上面的这个冰淇淋球的体积要小于等于下面的冰淇淋球的二分之一,不然就没法堆起来成一个冰淇淋。问你最多能堆多少个冰淇淋。
思路:
我们可以用二分的方法,二分答案,判断答案x的时候,我们可以每x个一起判断,如果判断到n还没有结束的话,就直接返回不可能。
AC
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define LL long long
const int N=3e5+10;
LL a[N];
LL b[N];
int n,k;
int judge(int x)
{
for(int i=1;i<=x;i++)
{
b[i]=a[i];
}
int u=x+1;
for(int j=x+1;j<=k*x;j++)//x个数一起判断
{
while(u<=n&&a[u]<b[j-x]*2)
{
u++;
}
if(u==n+1)
{
return 0;
}
b[j]=a[u];
u++;
}
return 1;
}
int main()
{
int t;
int tot=1;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
}
sort(a+1,a+1+n);
int l=0,r=n/k;
int ans=0;
while(l<=r)
{
int mid=(l+r)/2;
if(judge(mid))
{
ans=mid;
l=mid+1;
}
else
{
r=mid-1;
}
}
printf("Case #%d: %d\n",tot++,ans);
}
return 0;
}