牛客周赛 Round 40(A,B,C,D,E,F)

news2024/11/23 12:58:06

比赛链接

官方讲解

这场简单,没考什么算法,感觉有点水。D是个分组01背包,01背包的一点小拓展,没写过的可以看看,这个分类以及这个题目本身都是很板的。E感觉就是排名放高了导致没人敢写,本质上是个找规律然后分类讨论。F是个数学算期望的题,纯数学,连取模都没用就用的浮点数。


A 小红进地下城

思路:

签到,比较一下两个串是否相同即可。

code:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

string s1,s2;

int main(){
	cin>>s1>>s2;
	puts((s1==s2)?"Yes":"No");
	return 0;
}

B 小红打怪

思路:

找到小红的位置,然后往她面对的方向走,看有几个怪就行了,很签到。

code:

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=1005;

int n,m;
char mp[maxn][maxn];
int fx[]={-1,1,0,0},fy[]={0,0,-1,1};

int sx,sy,st;

int main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>mp[i]+1;
		for(int j=1;j<=m;j++)
			if(mp[i][j]>='A' && mp[i][j]<='Z'){
				sx=i;
				sy=j;
				if(mp[i][j]=='W')st=0;
				else if(mp[i][j]=='S')st=1;
				else if(mp[i][j]=='A')st=2;
				else if(mp[i][j]=='D')st=3;
			}
	}
	
	int x=sx,y=sy,ans=0;
	do{
//		printf("(%d,%d)\n",x,y);
		ans+=(mp[x][y]=='*');
		x+=fx[st];
		y+=fy[st];
	}while(x>=1 && x<=n && y>=1 && y<=m);
	cout<<ans<<endl;
	return 0;
}

C 小红的排列构造

思路:

对第 i i i 个位置, a i a_i ai 一定是由 p i p_i pi q i q_i qi 给出,除此之外就没有什么限制了。

所以我们可以提出一个很简单的构造方法:先让 p p p 序列这个位置凑出 a i a_i ai,如果 p p p 序列没有这个数了(已经凑给其他位置了),那我们就让 q q q 序列去凑,如果都没有就无解。否则我们就得到了已经凑出了一部分的 p p p q q q。剩下的数没有限制,就依次补在空缺的位置上即可。

在一个序列剩余的数中查找还有没有某个数,并在给出这个数后把这个数删掉。我们可以用 s e t set set 来模拟这个过程,这题本质是个数据结构题。

code:

#include <iostream>
#include <cstdio>
#include <set>
using namespace std;
const int maxn=1e5+5;

int n,a[maxn];
int p[maxn],q[maxn];
set<int> s1,s2;

int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		s1.insert(i);
		s2.insert(i);
	}
	for(int i=1;i<=n;i++){
		if(s1.find(a[i])!=s1.end()){
			p[i]=a[i];
			s1.erase(a[i]);
		}
		else if(s2.find(a[i])!=s2.end()){
			q[i]=a[i];
			s2.erase(a[i]);
		}
		else {
			cout<<-1;
			return 0;
		}
	}
	for(int i=1,x;i<=n;i++){
		if(p[i])x=p[i];
		else {
			x=*s1.begin();
			s1.erase(s1.begin());
		}
		cout<<x<<" \n"[i==n];
	}
	for(int i=1,x;i<=n;i++){
		if(q[i])x=q[i];
		else {
			x=*s2.begin();
			s2.erase(s2.begin());
		}
		cout<<x<<" \n"[i==n];
	}
	return 0;
}

D 小红升装备

思路:

换个思路,我们把一件武器看成是一组物品,这组物品包含:不购买它,购买它,购买它并升若干级的所有情况的武器,这样就变成了分组背包问题(有 N N N 组,每一组你至多选择一个物品(也可以不选),每个物品都有自己的体积和价值,现在给你一个容里为 M M M 的背包,让你用这个背包装物品,使得物品价值总和最大)

但是一把武器你有可能升很多级,导致这把武器可能有很多种情况,但是发现我们的钱是有限的,只有 300 300 300,每升一级还至少要花一块钱,因此我们最多只用升 300 300 300 级,多了也没用,反正也买不起。这样我们枚举一组之内的武器时,只枚举到能买得起的武器等级就行了。

剩下就是分组背包,很板。

code:

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;
const int maxn=305;

int n,x;
ll dp[maxn][maxn];

int main(){
	cin>>n>>x;
	for(int i=1,a1,c1,c2,a2,mx;i<=n;i++){
		cin>>a1>>c1>>c2>>a2>>mx;
		
		for(int j=0;j<=x;j++)dp[i][j]=dp[i-1][j];
		for(int j=0,cst,val;j<=mx && c1+j*c2<=x;j++){
			cst=c1+j*c2;
			val=a1+j*a2;
			
			for(int k=cst;k<=x;k++)
				dp[i][k]=max(dp[i][k],dp[i-1][k-cst]+val);
		}
	}
	
	ll ans=0;
	for(int i=0;i<=x;i++)
		ans=max(ans,dp[n][i]);
	cout<<ans;
	return 0;
}

E 小红的矩阵划分

思路:

注意题面上 n n n 为偶数的条件。

不难想到,如果两种类型的砖都能填满矩阵的话,我们肯定用砖的平均价值最大的类型来填,这样总数是确定的,总价值就是最大的。

不过并不一定两种类型的砖都能填满矩阵。由于 n n n 是偶数的条件, 2 ∗ 2 2*2 22 的砖一定可以填满,但是 L L L 型的不一定。

进一步研究发现, 当 n n n 6 6 6 的倍数的时候,一定可以用 L L L 型砖块填满。一种可行的策略如下:我们用两个 L L L 型砖块合成一个 2 ∗ 3 2*3 23 矩形形状的方块,它又可以组合成 6 ∗ 6 6*6 66 形状的方块,因此一定可以填满 n n n 6 6 6 的倍数的情况。

n n n 不为 6 6 6 的倍数的时候,我们可以参考上面的填充方式,把整个方阵拆分成一个最大的边长为 6 6 6 的倍数的方阵和两个长为 6 6 6 的倍数的矩形,以及一个小方阵。如下图(1为边长为 6 6 6 的倍数的方阵,23为长为 6 6 6 的倍数的矩形,4为小方阵)

在这里插入图片描述
我们还是用两个 L L L 型砖块合成一个 2 ∗ 3 2*3 23 矩形形状的砖块来对上面的图形进行填充。因为 n n n 为偶数,而且还不是 6 6 6 的倍数,所以 23 的宽,以及 4 的边长要么是 2 2 2,要么是 4 4 4。123很明显可以 2 ∗ 3 2*3 23 的矩形来填充。然后剩下一个 2 ∗ 2 2*2 22 或者 4 ∗ 4 4*4 44 的小方阵。

如果只用 L L L 型砖块来填充,一定会剩下一个格子。我们可以选择把一个 L L L 型砖块替换成 2 ∗ 2 2*2 22 型砖块来利用上这个空闲的格子,不过如果 L L L 型砖块价值很高的话,这里也可能不替换会更优。

所以可能出现的情况我们已经全部讨论出来了。总结如下:

  1. n n n 6 6 6 的倍数的时候,有两种选择:
    1. L L L 型砖块填充满。
    2. 2 ∗ 2 2*2 22 型砖块填充满。
  2. n n n 不为 6 6 6 的倍数的时候,有三种选择:
    1. L L L 型砖块填充满,这时剩一个空闲格子。
    2. 2 ∗ 2 2*2 22 型砖块填充满。
    3. L L L 型砖块填充满,再把一个 L L L 型砖块替换成 2 ∗ 2 2*2 22 型砖块。

code:

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long ll;

ll n,x,y;

int main(){
	cin>>n>>x>>y;
	if(n%3==0)cout<<max(n*n/3*x,n*n/4*y);
	else cout<<max(max(n*n/3*x,n*n/3*x-x+y),n*n/4*y);
	return 0;
} 

F 小红拿宝箱

思路:

发现只取两个宝箱,而且只有一次不取的机会。情况很小,所以我们可以直接人力分情况讨论,分别计算期望。

我们取宝箱只有三种情况,

  1. 不取,取,取
  2. 取,不取 取
  3. 取,取

当只取一个宝箱的时候,使不使用不取的权利的时机还是比较好确定的,就是高于期望就取,否则就不取,重新抽卡。但是还能取两个宝箱的时候就不好说了。所以我们第一步是否取宝箱先分类讨论。分成不取和取的情况,如果不取,那么后面就只能随便取两个宝箱了,不能不取。如果取,那么后面可以取,也可以不取然后再取。

这样情况讨论就变成了:

  1. 不取
    1. 取,取
    1. 不取 取

先讨论第一步取了,现在我们不使用不取宝箱的权利(或者说我们已经用完了不取宝箱的权利),随便取两个宝箱的话,期望计算:

n n n 个数中随便取两个的方法数为 C n 2 C_n^2 Cn2,每个取法平分取到的概率,因此一种取法的概率就是 1 C n 2 \dfrac1{C_n^2} Cn21。计算每个取法的价值比较困难,但是所有取法的价值总和可以算。我们计算期望的时候可以先把概率提公因式,然后先计算所有取法的价值总和。

如果我们钦定第一个数取了 a 1 a_1 a1,另一个数可以取剩下的 n − 1 n-1 n1 个数,这样第一个数取 a 1 a_1 a1 的所有取法之和就为 s u m 1 = ( n − 1 ) ∗ a 1 + ( a 2 + a 3 + ⋯ + a n ) sum_1=(n-1)*a_1+(a_2+a_3+\dots+a_n) sum1=(n1)a1+(a2+a3++an),假设所有数之和 t o t = ∑ i = 1 n a i tot=\sum_{i=1}^{n}a_i tot=i=1nai,那么式子可以写为: s u m 1 = ( n − 2 ) ∗ a 1 + t o t sum_1=(n-2)*a_1+tot sum1=(n2)a1+tot,同理其他数作为第一个数,所以可以得到所有取法的总和 s u m = ∑ i = 1 n s u m i = ( n − 2 ) ∗ ( a 1 + a 2 + ⋯ + a n ) + n ∗ t o t = 2 ∗ ( n − 1 ) ∗ t o t sum=\sum_{i=1}^n{sum_i}=(n-2)*(a_1+a_2+\dots+a_n)+n*tot=2*(n-1)*tot sum=i=1nsumi=(n2)(a1+a2++an)+ntot=2(n1)tot

因为我们计算的时候为了方便是钦定了取数顺序的,但是实际上取数是没有顺序的,因此我们要消除排序的影响,对一种可行的方案,我们由于有顺序,所以得到的所有方案相当于对原本的取数方案进行了一次全排列,一个方案分裂成了全排列个数个方案。比如这里的 a 1 , a 3 a_1,a_3 a1,a3 的一个取数方案就变成 a 1 , a 3 a_1,a_3 a1,a3 a 3 , a 1 a_3,a_1 a3,a1 一共 A 2 2 A_2^2 A22 个方案。因此我们对整个方案除以一个 A 2 2 = 2 A_2^2=2 A22=2 就可以消除掉排序的影响了。因此总的取法之和就是 s u m = ( n − 1 ) ∗ t o t sum=(n-1)*tot sum=(n1)tot。于是期望就是 ( n − 1 ) ∗ t o t C n 2 = t o t / n ∗ 2 \dfrac{(n-1)*tot}{C_n^2}=tot/n*2 Cn2(n1)tot=tot/n2


如果第一步取了,假设取了 a i a_i ai,现在随机取一个宝箱的期望就是 t o t − a i n − 1 \dfrac{tot-a_i}{n-1} n1totai。如果我们下一步取到的宝箱价值大于等于期望,就取它,否则如果小于期望,就重新随机抽取。为了快速算出有多少宝箱的价值大于期望,我们可以给宝箱价值从小到大排个序,然后二分查找第一个大于等于期望的位置,这样后面的宝箱价值都大于等于期望,前面的都小。

假设第 i d id id 个宝箱就是第一个大于等于期望的位置。那么后面 i d id id 个宝箱不重抽,每个的期望是 a j n − 1 ( j ≥ i d ) \dfrac{a_j}{n-1}\quad(j\ge id) n1aj(jid),前 i d − 1 id-1 id1 个宝箱要重新抽取,每个的期望就是 t o t − a i n − 1 n − 1 \dfrac{\frac{tot-a_i}{n-1}}{n-1} n1n1totai,不过需要注意的是,两种情况中有一个会包含进 a i a_i ai ,判断一下然后减去即可。期望之和就是 1 n − 1 ∗ ( ∑ j = i d n a j + ( i d − 1 ) ∗ t o t − a i n − 1 − ( i ≥ i d   ? a i : t o t − a i n − 1 )   ) \dfrac{1}{n-1}*(\sum_{j=id}^{n}a_j+(id-1)*\frac{tot-a_i}{n-1}-(i\ge id\,?a_i:\frac{tot-a_i}{n-1})\,) n11(j=idnaj+(id1)n1totai(iid?ai:n1totai))。这里 ∑ j = i d n a j \sum_{j=id}^{n}a_j j=idnaj 可以预处理后缀和来快速查询。


上面两个讨论分别代表了取与不取第一个数的后续的期望,我们两个总的期望取大的即可。

注意特判 n = 1 n=1 n=1 的情况。

code:

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=1e5+5;

int n;
double a[maxn],suf[maxn],tot;

int main(){
	cin>>n;
	for(int i=1;i<=n;i++)cin>>a[i],tot+=a[i];
	if(n==1)return cout<<tot,0;
	sort(a+1,a+n+1);
	for(int i=n;i>=1;i--)suf[i]=suf[i+1]+a[i];
	
	double s1=tot/n*2;//任取两个的期望 
	double ans=0;
	for(int i=1;i<=n;i++){
		double s2=(tot-a[i])/(n-1);//拿走ai后任取一个的期望 
		int id=lower_bound(a+1,a+n+1,s2)-a;
		double tmp=suf[id]+(id-1)*s2;//分子部分 
		if(a[i]>=s2)tmp-=a[i];
		else tmp-=s2;
		tmp/=n-1;
		ans+=max(s1,tmp+a[i]);
	}
	printf("%.11lf\n",ans/n);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1617391.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

群辉安装python3教程

目录 群辉安装python3一、需求二、群辉套件安装python3三、ssh连接群辉&#xff08;一&#xff09;finshell连接群辉&#xff0c;root登录&#xff08;二&#xff09;安装pip3库&#xff08;三&#xff09;配置环境变量 四、测试 群辉安装python3 一、需求 需求&#xff1a;语…

【目标检测】YOLO系列-YOLOv1 理论基础 通俗易懂

为方便大家理解YOLO的原理&#xff0c;这里将YOLOv1的部分内容基础内容进行用比较直白的话和例子进行阐述&#xff0c;为后续大家学习YOLO作为铺垫。 1、模型所干的活 工作中&#xff0c;大家经常将 Word 文档 上传到某转换器&#xff0c;然后转换输出为PDF文档。目标检测中我…

认识rust中闻风丧胆生的命周期,不用过于担心,它对于所有人都是平等的

生命周期&#xff0c;简而言之就是引用的有效作用域。在大多数时候&#xff0c;我们无需手动的声明生命周期&#xff0c;因为编译器可以自动进行推导&#xff0c;用类型来类比下&#xff1a; 就像编译器大部分时候可以自动推导类型 <-> 一样&#xff0c;编译器大多数时候…

Rust Tracing 入门

Tracing 是一个强大的工具&#xff0c;开发人员可以使用它来了解代码的行为、识别性能瓶颈和调试问题。 Rust 是一种以其性能和安全保证而闻名的语言&#xff0c;在它的世界中&#xff0c;跟踪在确保应用程序平稳高效运行方面发挥着至关重要的作用。 在本文中探讨Tracing 的概…

4K Video Downloader v4.30.0.5644 一款专业级的4K视频下载器

4K Video Downloader 中文破姐版 本站所有素材均来自于互联网&#xff0c;版权属原著所有&#xff0c;如有需要请购买正版。如有侵权&#xff0c;请联系我们立即删除。

Multiscale Vision Transformers

1、引言 论文链接&#xff1a;https://arxiv.org/abs/2104.11227 Haoqi Fan[1] 等通过在 ViT[2] 中引入多尺度特征层次结构&#xff0c;提出了一种用于视频和图像识别的 Multiscale Vision Transformers(MViT)[1]。在视频识别任务中&#xff0c;它优于依赖大规模外部预训练的视…

react 基础学习笔记一

1、jsx语法过程 jsx使用react构造组件&#xff0c;通过bable进行编译成js对象&#xff0c;在用ReactDom.render()渲染成DOM元素&#xff0c;最后再插入页面的过程。 2、创建组件 组件的定义&#xff1a;将公用的代码组装成一个独立的文件&#xff0c;保持代码独立性&#xff0…

【QT学习】9.绘图,三种贴图,贴图的转换

一。绘图的解释 Qt 中提供了强大的 2D 绘图系统&#xff0c;可以使用相同的 API 在屏幕和绘图设备上进行绘制&#xff0c;它主要基于QPainter、QPaintDevice 和 QPaintEngine 这三个类。 QPainter 用于执行绘图操作&#xff0c;其提供的 API 在 GUI 或 QImage、QOpenGLPaintDev…

使用VPN后,浏览器访问不了国内地址解决办法

winR输入regedit 打开注册表 找到路径 计算机\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings删除两个proxy代理

【Android】 四大组件详解之广播接收器、内容提供器

目录 前言广播机制简介系统广播动态注册实现监听网络变化静态注册实现开机自启动 自定义广播发送标准广播发送有序广播 本地广播 内容提供器简介运行时权限访问其他程序中的数据ContentResolver的基本用法读取系统联系人 创建自己的内容提供器创建内容提供器的步骤 跨程序数据共…

JavaSE:抽象

一&#xff0c;抽象是什么&#xff0c;抽象和面向对象有什么关系 抽象&#xff0c;个人理解&#xff0c;就是抽象的意思 我们都知道面向对象的四大特征&#xff1a;封装&#xff0c;继承&#xff0c;多态&#xff0c;抽象 为什么抽象是面向对象的特征之一&#xff0c;抽象和面…

Aigtek功率放大器电路的主要作用是什么

功率放大器是电子电路中的一个重要组成部分&#xff0c;它的主要作用是将输入信号的能量放大到更大的幅度&#xff0c;以便驱动负载或传输信号。功率放大器广泛应用于各种领域&#xff0c;如音频放大器、射频放大器、通信设备、无线电设备等。下面我们将详细介绍功率放大器电路…

【NOI】C++算法设计入门之深度优先搜索

文章目录 前言一、深度优先搜索1.引入2.概念3.迷宫问题中的DFS算法步骤4.特点5.时间、空间复杂度5.1 时间复杂度 (Time Complexity)5.2 空间复杂度 (Space Complexity)5.3 小结 二、例题讲解1.问题&#xff1a;1586 - 扫地机器人问题&#xff1a;1430 - 迷宫出口 三、总结四、感…

Rust 使用结构体组织相关联的数据

目录 结构体的定义和实例化 使用字段初始化简写语法使用结构体更新语法从其他实例创建实例使用没有命名字段的元组结构体来创建不同的类型没有任何字段的类单元结构体结构体示例程序 通过派生 trait 增加实用功能方法语法 定义方法带有更多参数的方法关联函数多个 impl 块本文有…

日志

日志服务管理 在现实生活中&#xff0c;记录日志也非常重要&#xff0c;比如银行的转账记录&#xff0c;飞机上的黑盒子&#xff0c;那么将系统和应用发生的事件记录至日志中&#xff0c;以助于排错和分析使用日志记录的内容包括&#xff1a; 历史事件&#xff1a;时间&#…

甘特图:如何制定一个有效的产品运营规划?

做好一个产品的运营规划是一个复杂且系统的过程&#xff0c;涉及多个方面和阶段。以下是一些关键步骤和考虑因素&#xff0c;帮助你制定一个有效的产品运营规划&#xff1a; 1、明确产品定位和目标用户&#xff1a; 确定产品的核心功能、特点和优势&#xff0c;明确产品在市…

向量的点积和叉积的几何意义

1. 点积 点积(dot product)&#xff0c;又称标量积&#xff08;scalar product&#xff09;。结果等于。 可用于 判断的是否垂直求投影长度求向量是抑制作用还是促进作用计算两个向量的夹角 2. 叉积 叉积(cross product)&#xff0c;又称为向量积(vector product)。模长等…

【C++类和对象】日期类的实现

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

【深度学习实战(21)】使用thop.profile计算模型的FLOPs和Params

一、 含义 FLOPs&#xff08;计算量&#xff09;&#xff1a;注意s小写&#xff0c;是floating point operations的缩写&#xff08;这里的小s则表示复数&#xff09;&#xff0c;表示浮点运算数&#xff0c;理解为计算量。可以用来衡量算法/模型的复杂度。 Params&#xff08…

Dubbo应用可观测性升级指南与踩坑记录

应用从dubbo-3.1.*升级到dubbo-*:3.2.*最新稳定版本&#xff0c;提升应用的可观测性和度量数据准确性。 1. dubbo版本发布说明(可不关注) dubbo版本发布 https://github.com/apache/dubbo/releases 【升级兼容性】3.1 升级到 3.2 2. 应用修改点 应用一般只需要升级dubbo-s…