Python解题 - CSDN周赛第12期 - 蚂蚁的烦恼

news/2024/5/19 5:27:28/文章来源:https://blog.csdn.net/soonway2010/article/details/128173336

问哥本期有幸all pass,而且用时50分钟内。不过回想起来,本期的四道题目的设计都或多或少不太严谨,或者说测试用例不够全面(后面会细说)。这样的话就极有可能造成虽然通过了测试,拿到了分数,但代码却是有缺陷的、不可靠的,无法解决实际问题。尤其对一些和算法关系不大的题目来说,通过了测试真的代表不了什么。


第一题:豚鼠排名榜

已知字符A,B,C。每个字符都有自己的权值q。现不知道权值q,只知道A,B,C的三次比较结果。输出A,B,C可能的排列顺序,如果不存在,则输出Impossible。

示例:

输入

A<B

A<C

C>B

输出ABC

分析

本题比较简单,只有三个字母,相互关系也只有三种。而ABC三个字母的排列组合也只有六种,所以哪怕是穷举,将每种组合的字母依次拿出来去比较三种关系式,最多比较 3*6=18 次就可以得到答案。

本题没有说明给出比较的结果不会重复,比如说如果给出的输入是A<B,B>A,A<C,是无法得到答案的。所以问哥觉得这是题目描述不太严谨的地方,感觉又像是从哪里翻译摘抄过来的题目。

虽然本题用穷举完全可以pass,但是如果你想玩点“花”的,可以往下看。

因为只有三个字母,可以设定三个字母的初始权重都为0,根据三次比较(两两不重复)的比较结果,较小的一方权重减去10,较大的一方权重加上10。(可以加减任意数字,这里只是举例)

  • 如果存在组合,则三个字母最终的权重一定是-20、0、20,因为每个字母都比较了两次,最小的字母比另外两个字母都小,所以减了两次10,于是权重变成-20,而最大的字母同理,加了两次10,权重变成20。中间的字母各加减了一次10,所以权重回到0。
  • 如果不存在组合,则必有两个或以上的字母计算相同(均加减了一次或加、减两次),也就是最后的权重相同。

所以将三个字母最后的权重进行比较,如果存在相同的(重复),则表示不存在合理的组合。反之将字母按照权重从小到大排列输出即可。

参考代码

exp1 = input()
exp2 = input()
exp3 = input()d = {"A":0,"B":0,"C":0}
for i in (exp1,exp2,exp3):if i[1]==">":d[i[0]]+=10d[i[2]]-=10else:d[i[0]]-=10d[i[2]]+=10
if len(set(d.values()))<3:print("Impossible")
else:print("".join(sorted(d.keys(),key=lambda x:d[x])))

第二题:字符串转换

已知两个字符串a,b。字符串b中包含数量不等的特殊符号“.”,“*”(字符串存在没有特殊符号或者全由特殊符号组成的情 况)。“.”表示该字符可以变成任意字符,“* ”表示该字符的前一个字符可以变成任意多个。现在我们想知道b可否通过特殊符号变成a。如a* 可以转化为a,aa,aaa,aaaa…如果可以,则输出“yes”,反之输出“no”。

分析

本题不记得示例了,但是看完题目就知道这题在考正则表达式。因为正则表达式里“.”就代表任意字符,而“*”也代表前面的字符可以有任意数量。所以直接把字符串b当做正则表达式的pattern,去搜索字符串a就好,如果能找到,且找到的结果与a完全一致,证明b的pattern完全等价于a,意味着可以按照题目的要求变成a,则输出yes,如果找不到,则输出no。

但是本题的测试用例依然存在不严谨的地方。最明显的,正则里的“*”是量词,必须跟在某个字符后面,但是本题的测试用例里没有考虑“*”跟在“*”后面的情况,但是却出现了“*”出现在字符头部的情况。按照这种思想,如果出现“*”跟在“*”后面的情况,应该也是输出“no”才是,比如,aaaaa和a****,用正则去搜索会报错。

不过因为会报错,也比较容易发现问题。本题只需要特判“*”出现在字符头部的情况,剩下的就可以正常用正则来pass了。

如果要判别是否存在“*”连在一起的情况,需要 O(n) 的复杂度去检查字符串,也许是为了降低难度(虽然用Python的正则来实现可以说简直没有难度),本题没有考到,这里也就不给出代码了。不过本题如果考察的是用手工实现正则表达式的匹配,或者考察更多正则里的符号,如“?![^]”,难度就上去了。有兴趣的童鞋可以试试这个系列。

参考代码

a = input()
b = input()
import re
if b.startswith("*"):print("no")
else:c = re.search(b,a)if c and c.group()==a:print("yes")else:print("no")

第三题:蚂蚁家族

小蚂蚁群是一个庞大的群体,在这个蚂蚁群中有n只小蚂蚁,为了保证所有蚂蚁在消息传送的时候都能接收到消息,需要在他们之间建立通信关系。就是要求小蚂蚁都可以通过多只或者直接联系到其他人。已知几条小蚂蚁之间有通信关系,请问还需要再新建至少多少条关系?

输入:第一行n m,然后下面m行输入已存在的通信关系

示例

示例1示例2
输入

4 3

1 2

2 3

3 4

5 2

1 2

3 5

输出02

分析

本题实际上是本期里最难的,却又是最容易满分通过的,因为其测试数据存在隐含的有利条件,但是题目没有明说,那就是:

  1. 给出的每组通信关系都是左边小、右边大的;
  2. 每只蚂蚁都只有一个通信对象;
  3. 如果某只蚂蚁存在多个通信对象,则除了第一条以外都是环路(重复的)。

所以,由于存在上述隐含条件,通过此题变得极其简单,什么代码都不用写,直接给出 n-m-1 就能通过90%的测试用例。剩下的10%对应了第三条,存在环路,只要把通信关系左边的数字去重,得到新的个数m1,然后n-m1-1,就通过了。

参考代码1

通过本题所有测试的代码如下:

n, m = map(int, input().split())
m1 = set()
for i in range(m):m1.add(int(input().split()[0]))
print(n-len(m1)-1)

但是,正如问哥开头所说的,通过测试真的代表不了什么,因为该代码是有缺陷的!这是因为本题使用的测试用例很不严谨,存在了上述几条隐含的有利条件,使得问题变简单了,也漏掉了一些本可以找到正确答案的情况。比如,如果输入如下:

5 4

1 2

1 3

1 4

1 5

5只蚂蚁,存在4个通信关系,很显然,所有蚂蚁都可以通过1号蚂蚁与其它任意一只蚂蚁建立通信,所以需要增加的通信关系为0,也就是不需要增加通信关系,但是用这个代码是得不到正确答案的

深入思考

说回思路,本题很显然考察的是无向连通图。根据书本上关于连通图的基本知识,n个节点的连通图中至少存在n-1条边,如果存在多于n-1条边,则必存在环路。

比如上图里1、2、3都是连通图的形式,而图4则存在环路,导致节点4和5形成了“孤岛”,虽然总边数相同(都是n-1条),但却没有连通。

于是,如果没有环路的情况下,n-1(条边)减去m(条边)就是本题的答案,也就对应了本题测试数据里90%的情况。而剩下10%因为存在环路,所以要对m(条边)先去重。又因为本题测试数据里每个节点向下都只有一棵子树(隐含有利条件2),所以对节点去重就可以消除环路。

由于本题的测试数据只考察了图1和图4这两种情况,所以上面的代码就可以通过测试。可是如果测试数据包含了图2或图3这种情况,该怎么解题呢?

这种情况相对就要复杂不少,而且在比赛中既然已经all pass了,问哥就没有再去思考,所以后面这些讨论都是在赛后总结出来的,于是也没有去验证代码。这里问哥给出一种解法,是否准确还有待检验,但也算是一种思路吧。

由于可能存在多对多的边关系,比如1号蚂蚁和2/3/4/5号蚂蚁都有通信关系,这样的话使用上面的代码就没办法去除可能会形成环路的边了,实际上如果存在这种通信关系,想要去查找所有可能形成环路的边常常要深度搜索,并不轻松。

于是我们不妨换个思路,假设蚂蚁根据给出的通信关系组成一个个部落,而每个部落又相当于图里的一个节点(n个部落),所以只需要再添加部落个数减一(n-1)条边,就可以把节点全连通了,而只要节点之间连通,部落之间也就完全连通了。这时要注意的是,有可能有的蚂蚁不存在通信关系,所以单个蚂蚁就形成了自己的部落,这时也要参与到新的部落个数中来,所以最终的答案就是:部落个数+落单的蚂蚁个数-1

这样,我们也就无需去检查给出的哪些边是多余(形成环路)的了,因为多余的边(比如上图里的1--3)连接的本身就是部落里已经存在的蚂蚁,所以不会对部落的大小产生影响。

所以,根据上述思路,选择Python的集合来完成部落的建立非常适合,因为集合自动去重,时间复杂度低(in的查找为O(1))。

做法是这样:假设至少存在一对通信关系,则先将第一对通信关系的两只蚂蚁放进一个部落(集合)里,因为可能存在多个部落,所以将已存在的部落放进列表里。然后循环接收后面的通信关系,每接收到一对通信关系,就将列表中已存在的集合拿出来检查是否包含新的通信关系里至少一只蚂蚁,如果是,则将集合合并,如果不是,则已存在的集合再重新添加进列表,完成所有集合的比较后,再将新蚂蚁的集合添加进列表(这里使用的数据结构是队列,先进先出,所以如果在意时间复杂度的话,最好用python的内置deque来实现)。最后,再检查是否存在落单的蚂蚁(将所有蚂蚁的集合减去已存在的部落,得到的差集就是落单的蚂蚁),最后计算部落的个数加上落单蚂蚁的个数减去一。不考虑列表操作的情况下(或者使用队列,入队出队为常数级),时间复杂度为O(nm)未经检验,仅供参考

参考代码2

n, m = map(int, input().split())
res = [set(map(int, input().split()))]
for _ in range(1, m):a, b = map(int, input().split())new = {a,b}for _ in range(len(res)):temp = res.pop(0)if a in temp or b in temp:new.update(temp)else:res.append(temp)res.append(new)
single = set(range(1,n+1))
for i in res:single.difference_update(i)
print(len(res)+len(single)-1)

第四题:小股炒股

已知n天后的股票行情,现在已有的本金是m,规定只能入手一次股票和抛售一次股票。最大收益(含本金)是?

输入:第一行n m,第二行n个整数表示每天的股票行情

示例:

示例1示例2
输入

4 9

7 5 6 3

6 7

4 1 2 9 10 3

输出1070

分析

示例的具体数字我不记得了,大概就是这个样子,主要是为了更好的解释题目的意思。

这题其实没什么可说的,没什么难度。题目也很友好地把难度降低了:只能买、卖一次。所以只要遍历行情列表,通过比较不同买入点和卖出点的收益,找出最大收益时的买点和卖点即可,时间复杂度是O(n^2)。必定存在更优化的方案,但在比赛的时候来不及细想,我记得题目提示了n\leqslant 1000,所以穷举完全可以pass。

要注意的是,因为卖出的时间点必在买入之后,所以内循环只要从买入那天的隔天开始,到最后一天结束即可。

参考代码

n, m = map(int, input().split())
arr = list(map(int, input().split()))
res = m
for i in range(n):buy = arr[i]for j in range(i+1,n):sell = arr[j]if sell > buy:profit = (m//buy)*sell + m%buyres = max(res, profit)
print(res)

此题也存在测试数据的缺陷,比如代码在比较的过程中,只查找卖出和买入价格的最大比值(不计算最终收益),然后最后再通过该比值计算收益的话,也能通过测试。 但是如果数据是下面这个样子,两种方法得到的结果就不同了。

4 9

5 10 3 5

第1天买入、第2天卖出的价格比值为2,要大于第3天买入、第4天卖出的价格比值1.67。但是显然第3天买入、第4天卖出的收益(15)要高于前者(14)。这说明代码的测试数据存在考虑不全的情况,完全有机会使用不健全的代码“侥幸”通过测试。但是话说回来,存在即合理,谁能说这不是题目难度的一部分呢。

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构—链表

文章目录链表&#xff08;头插法、尾插法、单链表反转&#xff09;二分查找算法&#xff1a;哈夫曼编码构建链表insert()创建链表&#x1f447;【1】尾插法【2】头插法【3】遍历输出链表【4】输出链表的长度【5】查找链表上是否有该元素【6】指定位置插入数据链表经典面试题【1…

12家硬件厂商发布飞桨生态发行版 软硬一体协同发展

11月30日&#xff0c;由深度学习技术及应用国家工程研究中心主办、百度飞桨承办的WAVE SUMMIT2022深度学习开发者峰会如期举行。峰会上&#xff0c;百度AI技术生态总经理马艳军发布了飞桨深度学习平台的最新技术和生态进展&#xff0c;全新发布飞桨开源框架2.4版本&#xff0c;…

【论文简述】 Point-MVSNet:Point-Based Multi-View Stereo Network(ICCV 2019)

一、论文简述 1. 第一作者&#xff1a;Rui Chen、Songfang Han 2. 发表年份&#xff1a;2019 3. 发表期刊&#xff1a;ICCV 4. 关键词&#xff1a;MVS、深度学习、点云、迭代改进 5. 探索动机&#xff1a;很多传统方法通过多视图光度一致性和正则化优化迭代更新&#xff…

【Java实战】大厂都是怎样进行单元测试的

目录 一、前言 二、单元测试 1.【强制】好的单元测试必须遵守 AIR 原则。 2.【强制】单元测试应该是全自动执行的&#xff0c;并且非交互式的。测试用例通常是被定期执行的&#xff0c;执行过程必须完全自动化才有意义。输出结果需要人工检查的测试不是一个好的单元测试。不…

清华、北大、中科大、UMA、MSU五位博士生畅聊深度学习理论

点击蓝字关注我们AI TIME欢迎每一位AI爱好者的加入&#xff01;伴随着深度学习的蓬勃发展&#xff0c;进入人们视线的好像都是算法或AlphaGo等应用层面的东西。但是在理论上&#xff0c;深度学习似乎却没有很出圈的相关理论。因此&#xff0c;部分人也在批评深度学习是缺乏理论…

蓝海创意云·11月大事记 || 12月,暖心相伴

秋尽冬生&#xff0c;日短天寒 告别了立冬与小雪 时光不紧不慢开启了新一月的篇章 万物冬藏&#xff0c;沉淀酝酿 站在十二月的路口 蛰伏打磨&#xff0c;静待厚积而薄发 导 读 ● 客户端更新&#xff1a;新增PSD通道合成选项 ● 渲染案例&#xff1a;绝代双骄重启江湖…

Reading Note(10)——AutoBridge

这篇论文是FPGA 2021年的best paper award&#xff0c;主要解决的是在HLS编译过程中优化布局和布线&#xff0c;最终达到整个multi-die的FPGA板上的大规模HLS设计时钟频率尽可能提升的目的&#xff0c;这篇工作在当前chiplet工艺铺展开来的当下更加有现实意义&#xff0c;通过这…

浅谈ES标准的演变

ECMAScript从1997年第一版诞生依赖&#xff0c;经过无数人的“踩坑”和“填坑”&#xff0c;到现在&#xff0c;ES12呼之欲出。那么我们不妨讨论一下ES的发展历程&#xff0c;看它如何统一江湖&#xff0c;看它“曲折”而又令人期待的发展之路。 最近分析typescript&#xff0c…

jsp网络申报审批系统Myeclipse开发mysql数据库web结构java编程计算机网页项目

一、源码特点 JSP 网络申报审批系统 是一套完善的web设计系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为Mysql&#xff0c;使用…

16S全长测序揭示绿头虻肠道微生物及共生细菌

论文题目&#xff1a;Greenhead (Tabanus nigrovittatus) Wolbachia and Its Microbiome: A Preliminary Study 期刊&#xff1a;Microbiol Spectrum 研究背景 绿头虻&#xff08;Tabanus nigrovittatus&#xff09;的雌虫刺吸牲畜的血液&#xff0c;危害家畜&#xff0c;是美…

【从零开始学习深度学习】6.使用torchvision下载与查看图像分类数据集Fashion-MNIST

目录1.1 获取Fashion-MNIST数据集2.2 读取小批量小结图像分类数据集中最常用的是手写数字识别数据集MNIST。但大部分模型在MNIST上的分类精度都超过了95%。为了更直观地观察算法之间的差异&#xff0c;我们将使用一个图像内容更加复杂的数据集Fashion-MNIST。 本节我们将使用to…

分享几款免费实用的国产内网穿透工具

对于没有公网IP的用户来说&#xff0c;如何实现远程管理或让局域网的服务可以被公网访问到是一个问题。当然&#xff0c;也有很多类似的需求&#xff0c;比如&#xff1a; 微信公众号小程序开发调试公网访问本地web项目异地远程处理公司服务问题异地访问公司内网财务/管理系统…

什么是代码签名证书?

使用代码签名证书&#xff0c;您可以保证签名者的身份和软件的完整性&#xff0c;这可以防止在下载和安装软件时出现警告。 代码签名证书是软件开发人员用来签署其软件、应用程序和驱动程序代码的数字证书。它使用公私密钥基础设施(PKI)将实体绑定到公钥和私钥。 申请代码签名…

好用的数据恢复软件EasyRecovery2023最新版

实用的数据恢复软件有什么&#xff1f;电脑中的数据文件对很多的小伙伴来说都是非常重要的&#xff0c;在下载安装新的软件设备时都需要非常谨慎&#xff0c;一旦碰到一些病毒就可能会导致文件丢失&#xff0c;想要恢复这些文件并不是很容易&#xff0c;需要使用专业的数据恢复…

西部学刊杂志西部学刊杂志社西部学刊编辑部2022年第22期目录

百年党建与马克思主义中国化研究 党的纪律建设的实践、启示与创新——基于“三大纪律八项注意”的研究 武艳; 5-8 西部研究《西部学刊》投稿&#xff1a;cn7kantougao163.com 新疆红色资源运用现状调查研究——以南疆部分地区为例 王艺潼;努尔古扎丽阿不都克里木; 9-12…

毕业设计-基于机器视觉的深蹲检测识别-TensorFlow-opencv

目录 前言 课题背景和意义 实现技术思路 实现效果图样例 前言 &#x1f4c5;大四是整个大学期间最忙碌的时光,一边要忙着备考或实习为毕业后面临的就业升学做准备,一边要为毕业设计耗费大量精力。近几年各个学校要求的毕设项目越来越难,有不少课题是研究生级别难度的,对本科…

Flink

文章目录1. 概述1.1 Apache Flink1.2 特点1.3 Flink VS Spark Streaming2. 安装与部署2. Flink运行时的组件2.1 作业管理器(JobManager)2.2 任务管理器(TaskManager)2.3 资源管理器(ResourceManager)2.4 分发器&#xff08;Dispatcher)3. 任务提交流程4. Flink API4.1 不用级别…

红石外汇|每日汇评:在中国重新开放和OPEC+的推动下,欧元受到高度关注

1、本周开始欧元再次上涨&#xff0c;而美元则暴跌&#xff1b; 2、积极的美国就业数据和OPEC稳定的产量提升为经济回升提供前景&#xff1b; 3、市场对中国重新开放的渴望可能很快就会实现&#xff1b; 今天&#xff0c;由于美元再次面临压力&#xff0c;欧元兑美元在亚盘市…

window和linux的nacos安装

Nacos注册中心 Nacos是阿里巴巴的产品&#xff0c;现在是SpringCloud中的一个组件。相比Eureka功能更加丰富&#xff0c;在国内受欢迎程度较高 Nacos的下载 在Nacos的GitHub页面&#xff0c;提供有下载链接&#xff0c;可以下载编译好的Nacos服务端或者源代码&#xff1a; …

代码随想录刷题Day55 | 392. 判断子序列 | 115. 不同的子序列

代码随想录刷题Day55 | 392. 判断子序列 | 115. 不同的子序列 392. 判断子序列 题目&#xff1a; 给定字符串 s 和 t &#xff0c;判断 s 是否为 t 的子序列。 字符串的一个子序列是原始字符串删除一些&#xff08;也可以不删除&#xff09;字符而不改变剩余字符相对位置形…