非典型算法题,用程序和电脑玩一个游戏

2024-03-21 14:08

本文主要是介绍非典型算法题,用程序和电脑玩一个游戏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家好,欢迎阅读周末算法题专题。

今天选择的算法题是来自contest 1407比赛的C题,这题全场通过6700余人。通过的人数虽然多,但是这题真的不简单,想出算法来不太容易。抛开难度不提,这道题非常非常有意思,老实说这种形式的题目我也是第一次见。

题目链接:https://codeforces.com/contest/1407/problem/C

废话不多说,我们来看题目。

题意

这题是一道非典型的算法题,与其说是一道算法题不如说更像是一个游戏。游戏的目的是猜一个1至n这n个数构成的排列,我们需要通过输入和输出和系统进行交互,从系统处获取更多的信息,最终给出猜测的结果。

首先系统会给定一个整数n,表示这个排列由n个数字构成,这n个数字由前n个正整数构成,也就是1到n这n个数字。之后我们可以通过输出一个命令的形式向系统进行提问,提问的方式是? x y。系统会计算排列当中第x个数对第y个数取模的结果进行返回(排列的下标从1开始),也就是返回 n u m [ x ] % n u m [ y ] num[x] \% num[y] num[x]%num[y]的值。

系统最多接受2n次询问,当我们已经猜出整个排列之后,输出这个排列。其中 n ≤ 1 0 4 n \le 10^4 n104

样例

这个样例要倒过来看,第一个输入的3表示n。接着就先看输出再看输入。这个样例要猜的结果是[1, 3, 2],首先询问了num[1]对num[2]取余的结果,系统返回是1。接着询问num[3]对num[2]取余的结果,答案是2。接着询问num[1]%num[3]和num[2]%num[1],得到的结果分别是1和0。最终我们根据这些信息猜测出了这个排列是[1, 3, 2],通过! 1 3 2的形式进行返回。

思路

那道题之后我们首先可以发现,n确定了之后这n个数也就确定了。因为n最大,其他数对n取模都是它本身。所以我们需要先找到n的位置。

但是n的位置并不好找,想来想去只有一种办法,就是当出现两个数的余数是n-1的时候,就可以确定这两个数一个是n-1另外一个是n。但是很明显,这样做我们无法在规定步数内解出来。因为n个数两两组合一共有接近 n 2 n^2 n2种,但是题目限定我们最多只能询问2n次。

很显然,先找到n再寻找其他值是不行的。

既然这个想法不行,我又开始找起了其他方法。我们求了x % y的结果之后,究竟有什么用呢?这个结果到底有没有其他信息呢?

我们来简单分析一下,我们假设x % y = 1,那么这能说明什么吗?很明显,不能说明什么,因为可能性太多了。1对其他数取模都等于1,x % (x-1)也等于1。但假如x % y > (n/2) 呢?其实就能说明问题了。因为x和y的范围是[1, n],现在两个数取模之后的结果大于n的一半,很明显说明x就是这个结果,y是比x更大的数。还有一种情况是x % y = 0,这种情况我们虽然无法确定x和y的值,但是可以知道x一定是y的倍数且x > y。

虽然知道这些,但还是不够解开问题,仍然需要碰运气,因为我们并不能保证在查询次数内刚好就可以找到所有比二分之n大的数。但是这一段分析并不是无用的,我们可以在此基础上更进一步。我们求了x和y的余数之后可以再求一下y和x的余数,假设x % y = a, y % x = b,通过分析a和b我们能够得到什么结果呢?

首先我们可以肯定a和b不会相等,原因也很简单,因为x和y一定不等(排列中的数各不相同)。我们不妨假设x > y,那么y % x =b = y,x % y = a < y。如果a和b相等的话,那么就有 y < y,这显然是不成立的。所以可以肯定a和b一定不等。其次从上面的证明我们也看得出来,在x > y时,那么一定可以得到a < b。因为a = x % y < y,b = y % x = y。也就是说我们可以通过a和b的关系判断x和y的关系,不仅如此,还可以确定y的值。

到这里距离解出这道题已经非常接近了,只差临门一脚,但是这里我还是走了弯路。我当时的想法是把这些数两两配对,这样就可以确定出其中的一半。之后我们再把解不出来的数再进行配对,直到最后只剩下一个数为止。后来发现也有反例,比如[1, 3, 2, 4, 5],在这个例子当中1和3配对,2和4配对,5落单。我们还是没办法解出来。

我在这里苦思冥想了很久,后来才发现答案远在天边近在眼前,解法其实非常简单。我们只需要从前往后遍历维护一个最大值即可。我们假设最大值是id,凡是遇到小于id的数,都可以通过它和id取模的结果求出来。如果遇到了比id更大的数,同样可以通过取模的结果求出id。所以到最后的时候,我们可以求出除了最大值其他的所有数,这个剩下的数就是n。

想通了真的非常非常简单,说穿了一钱不值,但是要靠自己想明白还是不太容易的。并且这道题的题目形式也很新颖,非常非常有趣,适合在周末一玩。

最后,我们来看代码:

import sysdef guess(x, y):print('? {} {}'.format(x, y))# 输出之后需要flush一下,防止影响输入sys.stdout.flush()st = input()return int(st)st = input()n = int(st)
num = [-1 for _ in range(n+2)]# 一开始将最大值的下标设为1
idx = 1
for i in range(2, n+1):x = guess(idx, i)y = guess(i, idx)# 说明遇到了更大的数,那么x就是之前的最大值if x > y:num[idx] = xidx = i# 否则求出来的就是ielse:num[i] = ynum[idx] = nprint('! {}'.format(' '.join(map(str, num[1:n+1]))))

今天的问题到这里就结束了,衷心祝愿大家每天都有所收获。如果还喜欢今天的内容的话,请来一个三连支持吧~(点赞、关注、转发

原文链接,求个关注

在这里插入图片描述

这篇关于非典型算法题,用程序和电脑玩一个游戏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/832841

相关文章

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

sysmain服务可以禁用吗? 电脑sysmain服务关闭后的影响与操作指南

《sysmain服务可以禁用吗?电脑sysmain服务关闭后的影响与操作指南》在Windows系统中,SysMain服务(原名Superfetch)作为一个旨在提升系统性能的关键组件,一直备受用户关... 在使用 Windows 系统时,有时候真有点像在「开盲盒」。全新安装系统后的「默认设置」,往往并不尽编

Mac电脑如何通过 IntelliJ IDEA 远程连接 MySQL

《Mac电脑如何通过IntelliJIDEA远程连接MySQL》本文详解Mac通过IntelliJIDEA远程连接MySQL的步骤,本文通过图文并茂的形式给大家介绍的非常详细,感兴趣的朋友跟... 目录MAC电脑通过 IntelliJ IDEA 远程连接 mysql 的详细教程一、前缀条件确认二、打开 ID

基于Python编写自动化邮件发送程序(进阶版)

《基于Python编写自动化邮件发送程序(进阶版)》在数字化时代,自动化邮件发送功能已成为企业和个人提升工作效率的重要工具,本文将使用Python编写一个简单的自动化邮件发送程序,希望对大家有所帮助... 目录理解SMTP协议基础配置开发环境构建邮件发送函数核心逻辑实现完整发送流程添加附件支持功能实现htm

C#控制台程序同步调用WebApi实现方式

《C#控制台程序同步调用WebApi实现方式》控制台程序作为Job时,需同步调用WebApi以确保获取返回结果后执行后续操作,否则会引发TaskCanceledException异常,同步处理可避免异... 目录同步调用WebApi方法Cls001类里面的写法总结控制台程序一般当作Job使用,有时候需要控制

Python38个游戏开发库整理汇总

《Python38个游戏开发库整理汇总》文章介绍了多种Python游戏开发库,涵盖2D/3D游戏开发、多人游戏框架及视觉小说引擎,适合不同需求的开发者入门,强调跨平台支持与易用性,并鼓励读者交流反馈以... 目录PyGameCocos2dPySoyPyOgrepygletPanda3DBlenderFife

电脑提示d3dx11_43.dll缺失怎么办? DLL文件丢失的多种修复教程

《电脑提示d3dx11_43.dll缺失怎么办?DLL文件丢失的多种修复教程》在使用电脑玩游戏或运行某些图形处理软件时,有时会遇到系统提示“d3dx11_43.dll缺失”的错误,下面我们就来分享超... 在计算机使用过程中,我们可能会遇到一些错误提示,其中之一就是缺失某个dll文件。其中,d3dx11_4

游戏闪退弹窗提示找不到storm.dll文件怎么办? Stormdll文件损坏修复技巧

《游戏闪退弹窗提示找不到storm.dll文件怎么办?Stormdll文件损坏修复技巧》DLL文件丢失或损坏会导致软件无法正常运行,例如我们在电脑上运行软件或游戏时会得到以下提示:storm.dll... 很多玩家在打开游戏时,突然弹出“找不到storm.dll文件”的提示框,随后游戏直接闪退,这通常是由于

golang程序打包成脚本部署到Linux系统方式

《golang程序打包成脚本部署到Linux系统方式》Golang程序通过本地编译(设置GOOS为linux生成无后缀二进制文件),上传至Linux服务器后赋权执行,使用nohup命令实现后台运行,完... 目录本地编译golang程序上传Golang二进制文件到linux服务器总结本地编译Golang程序

使用Docker构建Python Flask程序的详细教程

《使用Docker构建PythonFlask程序的详细教程》在当今的软件开发领域,容器化技术正变得越来越流行,而Docker无疑是其中的佼佼者,本文我们就来聊聊如何使用Docker构建一个简单的Py... 目录引言一、准备工作二、创建 Flask 应用程序三、创建 dockerfile四、构建 Docker