2020 年百度之星·程序设计大赛 - 初赛三
2020 年百度之星·程序设计大赛 - 初赛三解题思路及代码(Discount、Game、Permutation)
1、Discount
Problem Description
学皇来到了一个餐馆吃饭。他觉得这家餐馆很好吃,于是就想办个会员。
一共有 nn 种会员充值卡套餐,假设学皇这餐饭的消费为 a 元,选择第 ii 种套餐,需要充值 b[i] * a 的钱,这次吃饭可以打 c[i]×10 折,由充值的钱支付(即这次吃饭只需要从充值金额中扣除 a×c[i] 元)。以后用剩余的充值的钱吃饭不再打折。
请问学皇应该选择哪个套餐(必须选择恰好一个套餐),使得优惠的比例最大?
优惠比例的定义是把充的钱用完以后,(本来应该付的钱 - 实际付的钱) / 本来应该付的钱。在这个题目里,实际付的钱就是这次充值的花费。Input
第一行一个整数 test(1≤test≤100) 表示数据组数。
对于每组数据,第一行一个正整数 n(1 \leq n \leq 100)n(1≤n≤100) 表示套餐的数目。
接下来 nn 行,每行一个正整数 b[i] (1≤b[i]≤100) 和一个小数 c[i](0≤c[i]≤1,c[i] 最多包含两位小数)。
Output
对于每组数据,输出一个五位小数表示最大的优惠比例。如果小数点后超过五位,四舍五入到五位。Sample Input
1
2
2 0.5
3 0.1
Sample Output
0.23077
样例解释
对于第一种套餐,优惠比例为 0.5a / (2a + 0.5a) = 0.2;
对于第二种套餐,优惠比例为 0.9a / (3a + 0.9a) = 9 / 39;
阅读题目,会感觉有点复杂,而且一些表达并不好理解,而这道题关键在于Sample Output,它给出了样例的解释说明,直观可以判断出题目最大优惠比例的计算方式,后续很容易解出题目。
Accept代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int test,i,j,n;
float c[],b[];
scanf("%d",&test);
while(test--)
{
scanf("%d",&n);
float r1=0.0,r=0.0;
for(i=;i<n;i++)
scanf("%f%f",&b[i],&c[i]);
for(i=;i<n;i++)
{
if((-c[i])/(b[i]+-c[i])>r)//计算每种方案的优惠比例,取最大值
r=(-c[i])/(b[i]+-c[i]);
}
printf("%.5f\n",r);
}
return ;
}
2、Game
Problem Description
Alice 和 Bob 在玩游戏。
桌面上有两堆金币,少的那堆有 x 个金币,多的那堆有 2x 个金币。
假设金币可以被无限细分。Alice 和 Bob 事先都不知道 x 是几,但是他们都知道 x 是一个 (0,1] 之间均匀分布的随机实数。
Alice 会等概率的被分配到其中的一堆金币,Bob 会得到另一堆。xx 的值和两堆金币的分配是相互独立的。
拿到金币以后,Alice 会马上数清自己拿到多少金币。然后 Alice 可以选择是否和 Bob 那堆换。
给定 Alice 拿到的金币数目,请问 Alice 要不要交换,使得她期望能得到的金币数目更多?
如果交换期望得到的金币数目多于不交换期望得到的金币数目,输出交换,否则不交换。Input
第一行一个正整数 test (1≤test≤200000) 表示数据组数。
接下来每行一个小数 p (0<p≤2),p 最多保留五位小数,表示 Alice 拿到的金币数目。
Output
对于每组数据,输出 Yes 表示需要交换,输出 No 表示不要交换。Sample Input
1
1.00000
Sample Output
Yes
先看了题目,差点被误导为难题,其实看了程序太简单了,实际理解起来类似于博弈问题,当Alice在游戏中要获得更多期望金币,必须从概率方面进行预测。
简而言之,当p>1时,Alice一定就是得到最大那堆金币了,所以一定不交换,因为p=2*x,x 是一个 (0,1] 之间均匀分布的随机实数;反之,当p<=1,存在Bob可能获得最大金币,所以Alice选择交换可能获得最大金币。
虽然存在Alice拿到0.8,Bob拿到0.4或者1.6,但是还是交换为好,碰运气。
目前官方提示: 当 p > 1 时,alice 拿到的一定是大的那部分,所以一定不换; 否则,alice 交换以后有一半概率翻倍,一般概率减半,0.25+0.50.5=1.25,所以一定换。
Accept代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int test;
float p;
cin>>test;
while(test--)
{
cin>>p;
if(p>1.0)
cout<<"No\n";
else
cout<<"Yes\n";
}
return ;
}
3、Permutation
Problem Description
一开始有 n 个数,他们按 1…n 的顺序排列,要求交换最多 m 对数字(同一个数字可以参与多次交换),使得逆序对数目最大。
对于一个序列 A,如果存在正整数 i,j 使得 1≤i<j≤n 而且 A[i] > A[j]A[i]>A[j],则 <A[i],A[j]> 这个有序对称为 A 的一个逆序对。Input
第一行一个正整数test (1≤test≤100000) 表示数据组数。
对于每组数据,一行两个整数 n,m (1≤n≤1000000,0≤m≤1000000) 表示数字个数和最多可以交换的数字对数。
Output
对于每组数据,一行一个整数表示答案。Sample Input
6
1 1
2 0
2 1
3 1
4 1
4 2
Sample Output
0
0
1
3
5
6
看到题目,在纸上写几个简单样例,就很容易发现这是一个找数学规律的题目,可推导出3种情况,具体见代码理解不难。
#include<bits/stdc++.h>
using namespace std;
int main()
{
int test,n,m,i;
scanf("%d",&test);
while(test--)
{
scanf("%d%d",&n,&m);
int nums=;
if(n==||m==)
nums=;
else if(m>=n/)//当交换次数>=数值向下取整的一半,退化为1+2+……+n-1之和
{
// for(i=1;i<=n-1;i++)
// nums+=i;
nums=n*(n-)/;//数学求和公式代替循环
}
else
{
int minum=n-*m;//此题关键,推导一般的情况,得到的逆序对
// for(i=minum;i<=n-1;i++)
// nums+=i;
nums=(minum+n-)*(n-minum)/;//数学求和公式代替循环
}
printf("%d\n",nums);
}
return ;
}
目前官方提示:
当 m≥⌊n/2⌋ 时,一定能变成 n...1,这时逆序对数最大。否则我们依次交换 1 和 n,2 和 n-1,.....,一共交换 m 对。
但是一个问题暂未解决,测试完全正确,而出现超时问题,可以看到我用数学求和公式代替循环,考虑可以解决问题,但是提交居然错误,还未找出原因。希望有大佬可以评论区提出方法,或者之后我解决了会更新AC代码。
我的博客园:https://www.cnblogs.com/chenzhenhong/p/13381296.html
我的CSDN博客:https://blog.csdn.net/Charzous/article/details/107596506
————————————————
版权声明:本文为CSDN博主「Charzous」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/Charzous/article/details/107596506
2020 年百度之星·程序设计大赛 - 初赛三的更多相关文章
- HDU6383 2018 “百度之星”程序设计大赛 - 初赛(B) 1004-p1m2 (二分)
原题地址 p1m2 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total ...
- HDU6380 2018 “百度之星”程序设计大赛 - 初赛(B) A-degree (无环图=树)
原题地址 degree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Tot ...
- HDU 6118 度度熊的交易计划 【最小费用最大流】 (2017"百度之星"程序设计大赛 - 初赛(B))
度度熊的交易计划 Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total S ...
- HDU 6119 小小粉丝度度熊 【预处理+尺取法】(2017"百度之星"程序设计大赛 - 初赛(B))
小小粉丝度度熊 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- HDU 6114 Chess 【组合数】(2017"百度之星"程序设计大赛 - 初赛(B))
Chess Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- HDU 6109 数据分割 【并查集+set】 (2017"百度之星"程序设计大赛 - 初赛(A))
数据分割 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- HDU 6108 小C的倍数问题 【数学】 (2017"百度之星"程序设计大赛 - 初赛(A))
小C的倍数问题 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- HDU 6122 今夕何夕 【数学公式】 (2017"百度之星"程序设计大赛 - 初赛(A))
今夕何夕 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submis ...
- HDU 6113 度度熊的01世界 【DFS】(2017"百度之星"程序设计大赛 - 初赛(A))
度度熊的01世界 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
随机推荐
- CString 十六进制转二进制
int nValude = 0; CString strtemp("asdb");; sscanf(strtemp.GetBuffer(0),"%x",& ...
- Nuxt+Express后端api接口配置与实现方式
Nuxt.js 是一个基于 Vue.js 的轻量级应用框架,可用来创建服务端渲染 (SSR) 应用.本文带你了解在 Nuxt.js 中使用 Express 如何编写实现后端的 api 接口. 创建接口 ...
- 深入理解JVM(③)Java的模块化
前言 JDK9引入的Java模块化系统(Java Platform Module System ,JPMS)是 对Java技术的一次重要升级,除了像之前JAR包那样充当代码的容器之外,还包括: 依赖其 ...
- 使用Fiddler模拟Post请求
做了一个动态的GIF来做演示,应该更加直观些. (完)
- WSL配置高翔vslam环境
WSL配置高翔vslam环境 步骤: 安装 windows wls 配置 g++ cmake 环境 编译运行一下例子 1. window启用 wsl 前往 "启用或关闭 Windows 功能 ...
- Python 3.10 的首个 PEP 诞生,内置类型 zip() 迎来新特性
译者前言:相信凡是用过 zip() 内置函数的人,都会赞同它很有用,但是,它的最大问题是可能会产生出非预期的结果.PEP-618 提出给它增加一个参数,可以有效地解决大家的痛点. 这是 Python ...
- WSL中文本地化
WSL中文本地化 Windows Subsystem for Linux(简称WSL)是一个在Windows 10上能够运行原生Linux二进制可执行文件(ELF格式)的兼容层.它是由微软与Canon ...
- linux磁盘容量不足的处理方案
在虚机上安装memcached时,突然发现磁盘空间不足. df -h 发现,磁盘一共12G,原来是新申请的虚机,磁盘分区没有挂载上. fdisk -l 查看磁盘,发现有 /dev/vdb1 /dev/ ...
- 「MoreThanJava」Day 3:构建程序逻辑的方法
「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...
- SCOI 2010 连续攻击游戏(贪心,图论)
SCOI 2010 连续攻击游戏 solution 直接就硬刚 我愿称贪心为暴力 因为题目中要求一定从小到大贪心,那么当前点的下标有能够选取的较大点,那么它一定可以和前面的一个较小点连接,所以可以直接 ...