2021年3月30日 百度笔试编程题第二题
描述:
牛牛有一个硬币,有p%的概率为正。现在要把一个数组 a[1]…a[2*n]拆分成n个二元组。对于这n个二元组,抛硬币,如果是正面就选择这两个数里最大的数字,反之则选最小的数字。
求最终和的结果的最大值的期望
输入:
第一行输入一个 n,一个p
第二行2*n个数据
输出:
如果是整数,则输出整数,如果是小数,则输出带%的数据
贪心即可。很容易知道,如果p%<0.5那么肯定得小的和小的组合,大的和大的组合,如果p%>0.5 那么肯定得小的和大的组合,大的和小的组合。
所以,先进行排序,然后判断p的大小,选择组合即可。
but 这样数据无法AC,应为数组的大小范围是1–1e11 ;n的范围是1–1e6,p的范围是0-1e2,累乘后是1e19。 所以long long也会爆。处理方法是,在加的过程就除掉100,并记录余数,最后进行总结即可
AC代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2e6+10;
ll n,p,a[maxn],ans=0,re=0;
int main(){
cin>>n>>p;
for(ll i=1;i<=2*n;i++){
cin>>a[i];
}
sort(a+1,a+1+2*n);
if(p<=50){
for(ll i=1;i<=2*n;i+=2){
ll cnt=(p*a[i+1]+(100-p)*a[i]);
ans+=cnt/100;
re+=cnt%100;//记录余数
}
}else{
for(ll i=1;i<=n;i++){
ll cnt=(p*a[2*n-i+1]+(100-p)*a[i]);
ans+=cnt/100;
re+=cnt%100;
}
}
//总结
if(re%100==0){//若余数的累加也是100的倍数,则答案肯定是个整数
printf("%lld\n",ans+re/100);
}else{//答案不是整数
ans+=re/100;//ans加上缺省值
re=re%100;//re对100取余
printf("%lld%lld%\n",ans,re);//直接输出即可
}
}