题解:P12257 [蓝桥杯 2024 国 Java B] 分组
mairuisheng · · 题解
题目:P12257 [蓝桥杯 2024 国 Java B] 分组
主要算法:贪心,双指针。
分析:
首先,判无解情况:分数中最大值小于分数中最小值的两倍一定不行,输出 0,结束程序。
否则用双指针求解:如果每组分两个同学,得到的是最优方案(剩下的同学可以分其他组)。所以先把数组
注意事项:考虑到最多分
以下代码用位运算优化乘除法。
C++ 代码:
#include<cstdio>
#include<algorithm>
#include<bitset>
using namespace std;
inline int read()
{
int x=0,f=1;
char s;
s=getchar();
while(s<48||s>57)
{
if(s=='-')f=-f;
s=getchar();
}
while(s>47&&s<58)
{
x=(x<<3)+(x<<1)+s-48;
s=getchar();
}
return x*f;
}
constexpr int N=1e5+1;
int n;
int a[N];
int maxn,minn=1e8;
bitset<N> vis;
int ans;
int main()
{
n=read();
int i;
for(i=1;i<=n;++i)
{
a[i]=read();
maxn=max(maxn,a[i]);
minn=min(minn,a[i]);
}
if(minn*2>maxn)//特判。
{
putchar('0');
return 0;
}
sort(a+1,a+1+n);
int l=n>>1,r=n;//双指针。
while(l>0)
{
if((a[l]<<1)>a[r])--l;
else
{
++ans;
vis[l]=true;
vis[r]=true;
--l,--r;
while(r>0&&vis[r])--r;
}
}
printf("%d",ans);
return 0;
}
Java 代码:
import java.util.Arrays;
import java.util.BitSet;
import java.util.Scanner;
public class Main
{
static final int N=100001;
static int n;
static int[] a=new int[N];
static int maxn, minn=(int)1e8;
static BitSet vis=new BitSet(N);
static int ans;
public static void main(String[] args)
{
Scanner scanner=new Scanner(System.in);
n=scanner.nextInt();
for(int i=1;i<=n;++i)
{
a[i]=scanner.nextInt();
maxn=Math.max(maxn,a[i]);
minn=Math.min(minn,a[i]);
}
if((minn<<1)>maxn)//特判。
{
System.out.print(0);
return;
}
Arrays.sort(a,1,n+1);
int l=n>>1,r=n;//双指针。
while(l>0)
{
if((a[l]<<1)>a[r])--l;
else
{
++ans;
vis.set(l);
vis.set(r);
--l;
--r;
while(r>0 &&vis.get(r))--r;
}
}
System.out.print(ans);
}
}